如何使用 .ui 文件使用 PyQt5 更改窗口/小部件? [英] How to change window/widget with PyQt5 using .ui files?

查看:42
本文介绍了如何使用 .ui 文件使用 PyQt5 更改窗口/小部件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

first of all thanks for your time and sorry for the question length, the real question is just the first part. I can't understand ho to realize a 'page' change, like a web application. I would like to do that using .ui files, representing widgets or main windows. Basically, I would like to have two classes, each one mapped with an .ui file implementing a view, and switch between the two views when a button is clicked.

我想要的是这样的:

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 文件以保持分隔.

After lots of researches I wrote the code below that almost realize that, I said almost because I must use the same class for all. What I want instead is to have one .py file for each .ui file to keep things separated.

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文字就可以看到页面变化了.它们是简单的小部件,每个小部件一个按钮

And this is the code for both .ui files, just change the filename to home.ui and second.ui, and change btn text to see the page change. They are simple widgets with one button each

<?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>

推荐答案

您需要做的是创建单独的小部件(而不是窗口).虽然其他类似问题已经涵盖了这一点(例如 this,由于文件要求不同,我无论如何都会回答.

What you need to do is to create separate widgets (not windows). While this is already covered in other similar questions (like this, I'll answer anyway due to the different files request.

解决方案仍然相同,使用 QStackedWidget,允许您可以在占据窗口相同部分的不同小部件之间切换,类似于 QTabWidget 所做的,但没有标签栏.

The solution is still the same, using a QStackedWidget, that allows you to switch between different widgets that occupy the same part of the window, similarly to what QTabWidget does, but without the tab bar.

首先,您需要在设计器中创建一个主窗口,在那里添加一个 QStackedWidget 并确保您删除所有它的页面(右键单击堆叠的小部件,然后在第 x 页,共 x 页"子菜单).
然后为每个页面创建单独的小部件(只需在创建新表单时出现的对话框中选择小部件").

First, you need to create a main window in designer, add a QStackedWidget there and ensure that you remove all of its pages (right click on the stacked widget, and select "Delete" in the "Page x of x" sub menu).
Then create separate widgets (just select "Widget" in the dialog that appears when creating a new form) for each page.

最后,在主窗口和每个子窗口小部件上使用 loadUi.我建议您将页面切换的逻辑保留在主窗口的代码中,而不是将其放在不同的页面中,因为在处理这种情况时,使用父"控制器是一种更好、更清晰的方法.

Finally, use loadUi on the main window and on each child widget. I'll recommend you to keep the logic of the page switching in the code of the main window, instead of having it in the different pages, as it's a better and cleaner approach having a "parent" controller when dealing with this situations.

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_()

第一个.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)

第二个.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,但通常建议使用适用于比您更复杂的情况.

There is also the possibility of using QWizard, but it's usually suggested for more complex cases than yours.

这篇关于如何使用 .ui 文件使用 PyQt5 更改窗口/小部件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆