我有一个需要将一个框架替换为另一个框架的要求。我已经实现了下面的代码,它工作正常,但问题是我在同一文件中进行操作。如果我在一个.py文件中创建frame1,而在另一个.py文件中创建frame2,仍然可以达到相同的结果,就可以吗?
以下解决方案将无济于事,因为它将在单个文件中创建大量代码。
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(434, 362)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(10, 10, 411, 311))
self.frame.setFrameShape(QtWidgets.QFrame.Box)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.frame_2 = QtWidgets.QFrame(self.centralwidget)
self.frame_2.setGeometry(QtCore.QRect(10, 10, 411, 311))
self.frame_2.setFrameShape(QtWidgets.QFrame.Box)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.label = QtWidgets.QLabel(self.frame_2)
self.label.setGeometry(QtCore.QRect(10, 10, 131, 16))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.frame)
self.label_2.setGeometry(QtCore.QRect(10, 20, 131, 16))
self.label_2.setObjectName("label_2")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(10, 330, 411, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.changeFrame)
MainWindow.setCentralWidget(self.centralwidget)
self.frame.show()
self.frame_2.hide()
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "Second Frame"))
self.label_2.setText(_translate("MainWindow", "First Frame"))
self.pushButton.setText(_translate("MainWindow", "Frame Change"))
def changeFrame(self):
self.frame.hide()
self.frame_2.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
from PyQt5 import QtCore, QtGui, QtWidgets
class Frame1(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(434, 362)
MainWindow.setWindowTitle("MainWindow")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(10, 10, 411, 311))
self.frame.setFrameShape(QtWidgets.QFrame.Box)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.label = QtWidgets.QLabel(self.frame_2)
self.label.setGeometry(QtCore.QRect(10, 10, 131, 16))
self.label.setObjectName("label")
self.pushButton.setText("Frame One")
MainWindow.setCentralWidget(self.centralwidget)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
Frame2.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Frame2(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(434, 362)
MainWindow.setWindowTitle("MainWindow")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(10, 10, 411, 311))
self.frame.setFrameShape(QtWidgets.QFrame.Box)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.label = QtWidgets.QLabel(self.frame_2)
self.label.setGeometry(QtCore.QRect(10, 10, 131, 16))
self.label.setObjectName("label")
self.label.setText("Second Frame")
MainWindow.setCentralWidget(self.centralwidget)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
Main.py
from PyQt5 import QtCore, QtGui, QtWidgets
from Frame1 import *
from Frame2 import *
class Main(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(434, 362)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
Frame1.frame.show()
Frame2.frame.hide()
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(10, 330, 411, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.changeFrame)
MainWindow.setCentralWidget(self.centralwidget)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def changeFrame(self):
Frame1.frame.hide()
Frame2.frame.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Main()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
答案 0 :(得分:0)
您的问题并不复杂,但是如果您需要进行许多改进:
如果要更改窗口小部件的可见性(而不是替换),则必须使用QStackedLayout或QStackedWidget。
在您的原始示例中,您使用QFrame,但在新代码中,您使用QMainWindow,这令人困惑,因为每个小部件都有一个目标,对于QMainWindow,它是具有预定义结构的窗口。因此,我将从头开始重新创建frame1.py和frame2.py。
由QtDesigner生成的代码不是小部件,因此必须将其他类用作基础(有关更多信息,请参见here)
考虑到上述情况,应该基于QFrame创建frame1和frame2的设计:
frame1.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Frame</class>
<widget class="QFrame" name="Frame">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>First Frame</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
frame2.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Frame</class>
<widget class="QFrame" name="Frame">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Second Frame</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
将.ui转换为.py:
pyuic5 frame1.ui -o frame1_ui.py -x
pyuic5 frame2.ui -o frame2_ui.py -x
创建frame1.py和frame2.py:
frame1.py
from PyQt5 import QtWidgets
from frame1_ui import Ui_Frame
class Frame1(QtWidgets.QFrame, Ui_Frame):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
frame2.py
from PyQt5 import QtWidgets
from frame2_ui import Ui_Frame
class Frame2(QtWidgets.QFrame, Ui_Frame):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
您必须使用与要显示的QFrame一样多的按钮创建QMainWindow,并建立QStackedWidget:
mainwindow.ui
<?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>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QStackedWidget" name="stackedWidget"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="btn1">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn2">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<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 class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
从.ui转换为.py:
pyuic5 mainwindow.ui -o mainwindow_ui.py -x
在main.py中执行逻辑:
main.py
from PyQt5 import QtWidgets
from mainwindow_ui import Ui_MainWindow
from frame1 import Frame1
from frame2 import Frame2
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.frame1 = Frame1()
self.frame2 = Frame2()
self.stackedWidget.addWidget(self.frame1)
self.stackedWidget.addWidget(self.frame2)
self.btn1.clicked.connect(self.on_clicked1)
self.btn2.clicked.connect(self.on_clicked2)
def on_clicked1(self):
self.stackedWidget.setCurrentIndex(0)
def on_clicked2(self):
self.stackedWidget.setCurrentIndex(1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())