2011-12-22 17 views
8

mam tej próbki kodu:zmiany rozmiaru okna dialogowego z 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_() 

go uruchomić, a kiedy moreButton kliknięciu ComboBox pojawia się lub znika. Zmienia się również rozmiar okna dialogowego. Ale jeśli zmienię metodę na:

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

(w celu ustawienia początkowego rozmiaru, gdy kombinacja jest ukryta) zmiana rozmiaru nie działa. Jeśli jednak kliknę przycisk resizeButton - który jest podłączony do tej samej metody - zmiana rozmiaru działa poprawnie.

Wiem, że istnieją inne sposoby osiągnięcia takiego wyniku (np. Layout.setSizeConstraint (QLayout.SetFixedSize)), ale chcę zadeklarować rozmiar jawnie.

Co robię źle?

Odpowiedz

5

Domyślam się, że próbujesz zmienić rozmiar QDialog zanim ma czas, aby ponownie dostosować jego wielkość po ciebie ukryj rzeczy. Tak więc na czas resize nazywa się minimumSize, który zapewnia, że ​​guziki i combobox są widoczne. Kiedy nazywasz to po pewnym czasie, ma teraz prawidłową wartość miminumSize i odpowiada poprawnie.

Quick Fix jest ręcznej minimumSize przed zmiana rozmiaru:

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) 

Ale gdybym uporać się z tym, że ja po prostu zostawić zarządzająca rozmiaru do układu i korzystać sizeConstraint. Tak właśnie są te układy.

+0

tak, to może być powód. działa poprawnie z tą zmianą. działa również z "layout3.setSizeConstraint (QLayout.SetNoConstraint)", jak wspomniano powyżej. Czy to drugie jest "lepszym" rozwiązaniem? – Ilias95

+0

W końcu zauważyłem, że w bardziej skomplikowanych sytuacjach (dlatego bardziej skomplikowanym ui) tylko ta odpowiedź działa dobrze. Dziękuję Ci bardzo! – Ilias95

1

próbowałeś tego? chyba że źle zrozumiem, to jest to, co chcesz zrobić.

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

edit: ostateczna odpowiedź jest layout3.setSizeConstraint (QLayout.SetNoConstraint)

+0

Udało mi się ustawić ramkę widoczną lub niewidoczną. "moreButton.toggled.connect (self.frame.setVisible)" jest odpowiedzialny za to. Problem polega na tym, że gdy ustawię niewidoczną ramkę, nie mogę przywrócić okna dialogowego do początkowego rozmiaru i jest puste miejsce. – Ilias95

+0

oh przepraszam, nie mogę teraz wymyślić innego rozwiązania z layout3.setSizeConstraint (QLayout.SetNoConstraint) – NotCamelCase

+0

tak, to wszystko. Dziękuję Ci! – Ilias95

2

Ten problem wydaje się być spowodowany kolejnością przetwarzania zdarzeń.

Oto prosty fix:

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

tak, to też działa. – Ilias95

3

To pytanie odpowiedzi były pomocne w mojej sytuacji: Automatyczny dobór z QDialog z QLayout/QVBoxLayout zawierający QLabel o zmiennej wielkości zawartości/wiadomości dla użytkownika, a jednocześnie unikanie podwójnego kursora na granicy całego kontenera QDialog. Rozmiar okna dialogowego ustawiono na Naprawiono, a strzałki pojawiałyby się, nawet jeśli nie można zmienić ich wielkości (nie zmieniłyby się). I chociaż wewnętrzny układ jest automatycznie/magicznie zmieniany, użycie SetFixedSize na układzie (niespodzianka, niespodzianka) sprawiło, że te denerwujące podwójne strzałki z ogólnego QDialog'a zniknęły.

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

... a teraz rozmiary dialogowych odpowiednio się do objętości zawartych na etykiecie jeszcze sam dialog nie jest (pozornie) użytkownika o zmiennym rozmiarze, co jest dobre dla informacji i komunikatów o błędach.

Wydawało mi się to sprzeczne z intuicją, więc pomyślałem, że warto dodać tutaj dla innych.
Trochę więcej szczegółów ...

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) 
Powiązane problemy