PyQt4

2011-12-22 13 views
8

के साथ एक संवाद का आकार बदलने मैं कोड के इस नमूना है:PyQt4

import sys 
from PyQt4.QtGui import (QApplication, QHBoxLayout, QVBoxLayout, QDialog, 
              QFrame, QPushButton, QComboBox) 

class Form(QDialog): 
    def __init__(self, parent=None): 
     super(Form, self).__init__(parent) 

     moreButton = QPushButton('moreButton') 
     moreButton.setCheckable(True) 
     resizeButton = QPushButton('Resize') 
     combo = QComboBox() 
     combo.addItems(['item1', 'item2']) 

     layout1 = QHBoxLayout() 
     layout1.addWidget(moreButton) 
     layout1.addWidget(resizeButton) 

     layout2 = QHBoxLayout() 
     layout2.addWidget(combo) 
     self.frame = QFrame() 
     self.frame.setLayout(layout2) 
     self.frame.hide() 

     layout3 = QVBoxLayout() 
     layout3.addLayout(layout1) 
     layout3.addWidget(self.frame) 

     moreButton.toggled.connect(self.frame.setVisible) 
     moreButton.clicked.connect(self.method) 
     resizeButton.clicked.connect(self.method) 

     self.setLayout(layout3) 
     self.resize(630, 50) 

    def method(self): 
     if self.frame.isVisible():   
      self.resize(630, 150) 
     else: 
      self.resize(630, 250) 

app = QApplication(sys.argv) 
form = Form() 
form.show() 
app.exec_() 

मैं इसे चलाने के लिए और जब moreButton क्लिक किया ComboBox दिखाई देता है या गायब हो जाता है। संवाद का आकार भी बदलता है। लेकिन अगर मैं इस विधि को बदलता हूं:

def method(self): 
    if self.frame.isVisible():   
     self.resize(630, 150) 
    else: 
     self.resize(630, 50) 

(कॉम्बो छुपाए जाने पर प्रारंभिक आकार सेट करने के लिए) आकार बदलना काम नहीं करता है। हालांकि, अगर मैं आकार बदलने पर क्लिक करता हूं बटन - जो एक ही विधि से जुड़ा हुआ है- आकार बदलना ठीक से काम करता है।

मुझे पता है कि इस तरह के परिणाम प्राप्त करने के अन्य तरीके हैं (उदाहरण के लिए लेआउट.सेट साइज़ कॉन्स्ट्रेन (QLayout.SetFixedSize)), लेकिन मैं आकार स्पष्ट रूप से घोषित करना चाहता हूं।

मैं क्या गलत कर रहा हूं?

उत्तर

5

मेरा अनुमान है कि इससे पहले कि आप इसे करने के लिए आप के बाद इसके आकार को पुन: एडजस्ट समय है QDialog आकार बदलने के लिए कोशिश कर रहे हैं सामान छुपाएं। तो उस समय resize कहा जाता है कि इसमें minimumSize है जो सुनिश्चित करता है कि बटन और combobox दिखाई दे। जब आप को कुछ समय के बाद पर कॉल करते हैं, तो अब यह उचित miminumSize है और ठीक से प्रतिक्रिया देता है।

एक त्वरित सुधार मैन्युअल रूप से आकार बदलने से पहले minimumSize अधिभावी है:

def method(self): 
    if self.frame.isVisible(): 
     # uncomment below, if you like symmetry :) 
     # self.setMinimumSize(630, 150) 
     self.resize(630, 150) 
    else: 
     self.setMinimumSize(630, 50) 
     self.resize(630, 50) 

लेकिन, अगर मैं इस से निपटने के लिए थे, मैं सिर्फ लेआउट के आकार बदलने के प्रबंधन छोड़ दो और sizeConstraint का उपयोग करेंगे। वैसे भी इन लेआउट के लिए यही है।

+0

हां, यह कारण हो सकता है। यह इस परिवर्तन के साथ ठीक से काम करता है। यह ऊपर वर्णित अनुसार "layout3.setSizeConstraint (QLayout.SetNoConstraint)" के साथ भी काम करता है। क्या उत्तरार्द्ध एक "बेहतर" समाधान है? – Ilias95

+0

अंततः मैंने देखा कि अधिक जटिल परिस्थितियों में (इसलिए अधिक जटिल ui) केवल यही जवाब ठीक काम करता है। आपका बहुत बहुत धन्यवाद! – Ilias95

1

क्या आपने इसे आजमाया? जब तक मैं गलत समझ नहीं लेता, यह वही है जो आप करना चाहते हैं।

def method(self): 
    if self.frame.isVisible(): 
     self.resize(630, 150) 
     self.frame.setVisible(False) 
    else: 
     self.resize(630, 50) 

संपादित करें: अंतिम जवाब layout3.setSizeConstraint (QLayout.SetNoConstraint) है

+0

मैंने फ्रेम को दृश्यमान या अदृश्य सेट करने में कामयाब रहा है। "moreButton.toggled.connect (self.frame.setVisible)" इसके लिए ज़िम्मेदार है। समस्या यह है कि जब मैं फ्रेम को अदृश्य सेट करता हूं तो मैं अपने शुरुआती आकार में संवाद वापस नहीं ला सकता हूं और कुछ रिक्त स्थान है। – Ilias95

+0

ओह क्षमा करें, तो अब मैं layout3.setSizeConstraint (QLayout.SetNoConstraint) – NotCamelCase

+0

हाँ से एक अलग समाधान के बारे में सोच नहीं सकता हूं। धन्यवाद! – Ilias95

2

यह समस्या उस क्रम के कारण होती है जिसमें ईवेंट संसाधित होते हैं।

यहाँ एक सरल ठीक है:

def method(self): 
    app.processEvents() 
    if self.frame.isVisible():   
     self.resize(630, 150) 
    else: 
     self.resize(630, 50) 
+0

हाँ, यह भी काम करता है। – Ilias95

3

यह सवाल और जवाब मेरी स्थिति में मददगार थे: QLayout/QVBoxLayout उपयोगकर्ता के लिए चर आकार सामग्री/संदेश की एक QLabel युक्त के साथ एक QDialog की स्वचालित साइज़िंग करते हुए भी कुल QDialog कंटेनर की सीमा पर डबल तीर कर्सर से परहेज करें। संवाद का आकार स्वयं को फिक्स्ड पर सेट किया गया था और फिर भी तीर दिखाई देंगे, भले ही इसका आकार बदला नहीं जा सके (कड़वाहट नहीं होगी)। और भले ही आंतरिक लेआउट लेआउट (आश्चर्य, आश्चर्य) पर SetFixedSize का उपयोग करके स्वचालित रूप से/जादुई आकार बदलता है, लेकिन कुल QDialog के उन परेशान डबल तीरों को दूर कर दिया जाता है।

QDialog: QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) 
QLayout: setSizeConstraint(QLayout.SetFixedSize) 
QLabel: QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) 

... और अब संवाद आकार ही उचित रूप से वॉल्यूम लेबल में निहित करने के लिए अभी तक संवाद ही नहीं (प्रतीत होता है) उपयोगकर्ता के आकार बदलने योग्य है, जो जानकारी और त्रुटि संदेश के लिए अच्छा है।

मेरे लिए समेकित समझा गया तो मैंने दूसरों के लिए यहां जोड़ने के लायक विचार किया।
थोड़ा और विस्तार ...

self.label = QtGui.QLabel(self) 
self.label.sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) 
self.label.setSizePolicy(self.label.sizePolicy) 
self.label.setMinimumSize(QtCore.QSize(450, 40)) 
self.label.setWordWrap(True) 

self.verticalLayout = QtGui.QVBoxLayout(self) 
# get rid of overall dialog resize arrows 
self.verticalLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize) # no resize arrows 
self.verticalLayout.addWidget(self.label)