В вашем коде есть большая концептуальная проблема, и только из-за тонкого "не-ошибки" в Qt ваша программа "кажется" работает (как в "она работает = она показывает") ").
Основная проблема заключается в том, что вы пытаетесь наследовать от QMainWindow _ и _ QWidget, что не имеет особого смысла, поскольку QMainWindow уже наследует QWidget.
На самом деле вы видите не ваше главное окно (экземпляр Main
), но все отдельные QWidget, которые вы создали (self.login
, et c.).
Это «не ошибка» (вероятно, связанная с этим отчетом ): когда новый виджет добавляется в QStackedLayout, он пытается показать его. Если в макете с накоплением нет виджета в конструкторе и не установлен ни один виджет, по какой-то причине Qt показывает этот виджет, как только приложение exec
'd.
Это не должно делать это да, но вы также не должны создавать макет, не устанавливая его в виджет (так как вы не должны обычно создавать класс с множественным наследованием, совместно использующим одного и того же прямого предка, в данном случае QWidget). Также происходит то, что всякий раз, когда вы вызываете self.pages.setCurrentIndex
, макет с накоплением пытается показать новый виджет и скрыть предыдущий. Это нормально для нормальных ситуаций (чаще всего, когда используется QStackedWidget, но у вас неожиданный результат: поскольку для стекового макета не установлен виджет, его виджет вообще не должен отображаться (на самом деле его поведение технически не является техническим) не так, но проблема не в этом).
Решение состоит в том, чтобы реализовать все в классе Main
, создать центральный виджет и установить компоновку для этого виджета.
class Main(QMainWindow, UI):
def __init__(self):
super(Main, self).__init__()
self.setupUI(self)
self.loginButton.clicked.connect(self.GoTohomePage)
self.Button1.clicked.connect(self.GoTologinPage)
def setupUI(self, Main):
self.width = 900
self.height = 500
<b>centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.pages = QStackedLayout()
centralWidget.setLayout(self.pages)</b>
# the two lines above are the same as the following:
# self.pages = QStackedLayout(centralWidget)
self.login = QWidget()
self.register = QWidget()
self.home = QWidget()
self.loginUI()
self.homeUI()
self.pages.addWidget(self.login)
self.pages.addWidget(self.home)
def loginUI(self):
self.login_Layout = QGridLayout(self.login)
self.login.setFixedSize(300, 200)
self.loginButton = QPushButton("Log In")
self.login_Layout.addWidget(self.loginButton, 0, 0)
def homeUI(self):
self.home_Layout = QGridLayout(self.home)
self.home.setFixedSize(self.width, self.height)
self.Button1 = QPushButton("Log Out")
self.Button2 = QPushButton("HELLO")
self.home_Layout.addWidget(self.Button1, 0, 0, 1, 1)
self.home_Layout.addWidget(self.Button2, 0, 1)
def keyPressEvent(self, event):
if event.key() == Qt.Key_Escape:
print("closed")
def GoTohomePage(self):
self.pages.setCurrentIndex(1)
def GoTologinPage(self):
self.pages.setCurrentIndex(0)
if __name__ == "__main__":
app = QApplication(sys.argv)
M = Main()
<b>M.show()</b>
sys.exit(app.exec())
Как видите, я включил весь код в один класс с некоторыми важными изменениями:
- Я создал новый виджет, который установлен как центральный виджет , который почти обязателен для любого класса QMainWindow (чтобы узнать больше об этом, прочитайте документацию об этом);
- составной макет применяется к центральному виджету ;
- экземпляр окна явно показан (с использованием
M.show()
)
С этими простыми изменениями keyPressEvent
теперь правильно перехвачен. A Также я считаю, что я пытался оставить большую часть вашего кода нетронутым, но для того, что я вижу, вы должны вместо этого использовать QStackedWidget, который ведет себя таким же образом, но, как виджет, у него есть лучшие способы управления его содержимым:
def setupUI(self, Main):
self.pages = QStackedWidget()
self.setCentralWidget(self.pages)
self.width = 900
self.height = 500
self.login = QWidget()
self.register = QWidget()
self.home = QWidget()
self.loginUI()
self.homeUI()
self.pages.addWidget(self.login)
self.pages.addWidget(self.home)
# ...
Наконец, если вы хотите использовать разные размеры окон для каждого «диалогового» окна, вам вообще не следует использовать сложенный объект на основе, поскольку он основывает подсказку о размере на «самом большом» виджете, который он содержит. Если вы этого не хотите, вы можете явно использовать self.setFixedSize(width, height)
в окне каждый раз, когда изменяется «страница», но я бы не советовал.
PS: Я полагаю, что вы сделали ошибка множественного наследования при попытке понять, как используется вывод pyuic
, или как-то неправильно понять документацию о с помощью Designer ; может быть, чрезмерная ошибка, но честная ;-). Я искренне надеюсь, что никто не говорил вам создавать подобные виджеты ... если это так, позор ему / ей: это полностью неправильно!