如何使用.ui文件使用PyQt5更改窗口/窗口小部件?

问题描述 投票:0回答:1

首先,感谢您的宝贵时间,对问题的长度感到抱歉,真正的问题只是第一部分。我无法理解ho如何实现“页面”更改,例如Web应用程序。我想使用代表小部件或主窗口的.ui文件来执行此操作。基本上,我想有两个类,每个类都映射有一个实现视图的.ui文件,并在单击按钮时在两个视图之间切换。

我想拥有这样的东西:

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        # then load the home page file home.ui

class HomePage:
    def method_0(self):
        # method to load and show the home.ui file, at startup

    def method_1(self):
        # method to load and show the home.ui file, when a button in Second Page is pressed

class SecondPage
    def method_1(self):
        # method to load and show the second.ui file when a button in HomePage is pressed

if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec_()

经过大量研究,我在下面编写了几乎意识到这一点的代码,我之所以这样说,几乎是因为我必须对所有人使用相同的类。相反,我想要的是每个.ui文件都有一个.py文件,以保持分隔。

from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow, QStackedWidget

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.resize(800, 620)
        self.central_widget = QStackedWidget()
        self.setCentralWidget(self.central_widget)
        self.home_page()

    def home_page(self):
        widget = uic.loadUi('home.ui')
        self.central_widget.addWidget(widget)
        self.central_widget.setCurrentWidget(widget)
        widget.change_btn.clicked.connect(self.second_page)

    def second_page(self):
        widget = uic.loadUi('second.ui')
        self.central_widget.addWidget(widget)
        self.central_widget.setCurrentWidget(widget)
        widget.change_btn.clicked.connect(self.home_page)


if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec_()

这是两个.ui文件的代码,只需将文件名更改为home.uisecond.ui,然后更改btn文本以查看页面更改。它们是简单的小部件,每个小部件都有一个按钮

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>620</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Application</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <property name="title" stdset="0">
    <string>GroupBox</string>
   </property>
   <widget class="QPushButton" name="change_btn">
    <property name="geometry">
     <rect>
      <x>285</x>
      <y>170</y>
      <width>230</width>
      <height>40</height>
     </rect>
    </property>
    <property name="font">
     <font>
      <pointsize>12</pointsize>
     </font>
    </property>
    <property name="text">
     <string>Change page</string>
    </property>
   </widget>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>
python user-interface pyqt pyqt5
1个回答
0
投票

您需要做的是创建单独的widgets(不是Windows)。尽管其他类似问题(例如this)已经解决了这一问题,但由于文件请求不同,我还是会回答。

解决方案仍然是相同的,使用QStackedWidget,允许您在占据窗口同一部分的不同小部件之间进行切换,类似于QTabWidget所做的,但是没有选项卡栏。

首先,您需要在设计器中创建一个主窗口,在其中添加一个QStackedWidget并确保删除其页面的all(右键单击堆叠的窗口小部件,然后在“页面x的页面”中选择“删除” x“子菜单)。然后为每个页面创建单独的widgets(只需在创建新表单时出现的对话框中选择“小部件”)。

最后,在主窗口和每个子窗口小部件上使用loadUi。我建议您将页面切换的逻辑保留在主窗口的代码中,而不是将其置于不同的页面中,因为在处理这种情况时,这是一种更好的方法,它具有“父”控制器。 >

pages.py:

from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow

from first import First
from second import Second

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi('pages.ui', self)
        self.first = First()
        self.stackedWidget.addWidget(self.first)
        self.first.change_btn.clicked.connect(self.go_to_second)
        self.second = Second()
        self.stackedWidget.addWidget(self.second)
        self.second.change_btn.clicked.connect(self.go_to_first)

    def go_to_first(self):
        self.stackedWidget.setCurrentIndex(0)

    def go_to_second(self):
        self.stackedWidget.setCurrentIndex(1)


if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec_()

first.py

from PyQt5 import uic
from PyQt5.QtWidgets import QWidget

class First(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        uic.loadUi('first.ui', self)

second.py

from PyQt5 import uic
from PyQt5.QtWidgets import QWidget

class Second(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        uic.loadUi('second.ui', self)

也有可能使用QWizard,但通常建议比您的情况更复杂的情况。

© www.soinside.com 2019 - 2024. All rights reserved.