从另一个文件中打开PyQT GUI文件

7 投票
2 回答
15534 浏览
提问于 2025-04-17 15:07

我在用QT Designer创建了很多PyQT的图形界面,但现在我想从一个界面打开另一个界面,不知道该怎么做。Start.py是运行图形界面Authentification_1的文件,而Acceuil_start.py是运行图形界面Acceuil_2.py的文件。现在我想从Start.py启动Acceuil_start.py。你有什么想法吗?谢谢!以下是我的代码:

Start.py:

import sys
from PyQt4 import QtCore, QtGui
from Authentification_1 import Ui_Fenetre_auth
from Acceuil_2 import Ui_MainWindow #???  Acceuil_2.py is the file which I want to open

class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_Fenetre_auth()
        self.ui.setupUi(self)

    def authentifier(val): #Slot method
        self.Acceuil = Acceuil() #???
        self.Acceuil.show() #???


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = StartQT4()
    myapp.show()
    sys.exit(app.exec_())

Acceuil_start.py

import sys
from PyQt4 import QtCore, QtGui
from Authentification_1 import Ui_Fenetre_auth
from Acceuil_2 import Ui_MainWindow

class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = StartQT4()
    myapp.show()
    sys.exit(app.exec_())

2 个回答

0

要在Start.py中引用另一个对话框,你需要在前面加上模块的名字,这里是Acceuil_start。所以,如果每个模块里有相同的函数名也是没问题的。这样你就可以写:

def authentifier(val): #Slot method
    dlg = Acceuil_start.StartQT4()
    dlg.exec_()

不过,如果你想让这些在同一个进程中运行,要记住不能有两个app对象。你可能需要把Acceuil_start.py设计成一个对话框,而不是主窗口。如果这两个是完全不同的主窗口,你可能会觉得直接用另一个Python解释器来运行Acceuil_start.py更简单。

3

首先,你应该给你的图形界面(GUI)类起个不同的名字,而不是用通用的名字,这样你才能区分它们。

为什么要这么做呢?其实很简单,因为这样更有意义。如果每个类代表不同类型的对话框,那它们就是不同的类型,自然应该有不同的名字。一些可能的名字包括:QMessageBoxAboutBoxAddUserDialog等等。

在 Acceuil_start.py 中(你也应该在其他模块中重命名类)。

import sys
from PyQt4 import QtCore, QtGui
from Authentification_1 import Ui_Fenetre_auth
from Acceuil_2 import Ui_MainWindow

class Acceuil(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = Acceuil()
    myapp.show()
    sys.exit(app.exec_())

在父类中,当你想创建窗口时,你已经接近了(但在任何情况下都应该能工作):

def authentifier(val): #Slot method
    self.Acceuil = Acceuil(self) # You should always pass the parent to the child control
    self.Acceuil.show() #???

关于父类的问题:如果你的控件/窗口正在创建另一个控件,把创建者对象设置为父对象总是个好主意(除了某些特殊情况),你应该阅读这个链接来了解原因:

QObject 会以树状结构组织自己。当你创建一个 QObject,并把另一个对象作为父对象时,它会被添加到父对象的子对象列表中,并在父对象被删除时一起删除。这个方法非常适合图形界面对象。例如,QShortcut(键盘快捷键)是相关窗口的子对象,所以当用户关闭那个窗口时,快捷键也会被删除。

编辑 - 最小工作示例

为了让你明白我想表达的意思,我做了一个简单的例子。你有两个类 - MainWindowChildWindow。每个类都可以独立工作,创建各自的 QApplication 对象。但是,如果你在 MainWindow 中导入 ChildWindow,你会在与单次定时器连接的槽中创建 ChildWindow,这个定时器会在5秒后触发。

MainWindow.py:

import sys
from PyQt4 import QtCore, QtGui
from ChildWindow import ChildWindow

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        QtCore.QTimer.singleShot(5000, self.showChildWindow)


    def showChildWindow(self):
        self.child_win = ChildWindow(self)
        self.child_win.show()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = MainWindow()
    myapp.show()
    sys.exit(app.exec_())

ChildWindow.py:

import sys
from PyQt4 import QtCore, QtGui

class ChildWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setWindowTitle("Child Window!")


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = ChildWindow()
    myapp.show()
    sys.exit(app.exec_())

撰写回答