PyQt多窗口 - 如何在模块之间传递函数 Qt Designer

3
我先提出问题,再尝试解释一下: 一个导入的模块是否有办法调用导入它的模块中的函数?
我正在学习使用Qt,从Qt Designer入手以便掌握一些基本知识。
我已经找到了创建多个“.ui”文件的方法,以获取多个窗口的代码,并成功地实现了通过导入两个窗口的代码从主应用程序调用多个窗口的功能。
例如,从win1.ui和win2.ui开始,我创建了win1.py和win2.py——从我的主应用程序中,我导入了win1和win2...
注意-我通过遵循这个简单的教程做到了这一步: http://www.youtube.com/watch?v=bHsC6WJsK-U&list=PLF4575388795F2531&index=10&feature=plpp_video 好的,现在是问题。如果我在win2中有一个按钮,我知道如何将该按钮链接到win2.py代码中的一个函数。但我不知道如何将win2中的按钮链接到主应用程序中的一个函数。
我唯一的想法是将一个函数作为设置第二个窗口的类的参数添加进去,但如果我这样做,那么对win2.ui的任何更改都将破坏我所做的更改。
因此,一个导入的模块是否有办法调用导入它的模块中的函数?
我希望这很清楚,不需要添加一堆不相关的代码...
1个回答

4
Qt基于事件驱动编程。通常情况下,在构建部件时,您需要通过信号向接收器部件提供信息,然后再进行处理。您不希望一个子部件明确知道或需要在父部件上调用方法(这并非总是如此,但尽可能避免更好)。
我将发布一些没有UI文件的示例,以便于在此处进行,但请假定您可以使用设计者构建相同的部件,并以相同的方式工作... testwidget.py
from PyQt4 import QtGui, QtCore

class TestWidget(QtGui.QWidget):
    textSaved = QtCore.pyqtSignal(str)

    def __init__( self, parent = None ):
        super(TestWidget, self).__init__(parent)

        # create the ui (or load it)
        self.__edit   = QtGui.QTextEdit(self)
        self.__button = QtGui.QPushButton(self)
        self.__button.setText('Save')

        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.__edit)
        layout.addWidget(self.__button)
        self.setLayout(layout)

        # create connections
        self.__button.clicked.connect(self.emitTextSaved)

    def emitTextSaved( self ):
        # allow Qt's blocking of signals paradigm to control flow
        if ( not self.signalsBlocked() ):
            self.textSaved.emit(self.__edit.toPlainText())

testwindow.py

from PyQt4 import QtGui, QtCore
import testwidget

class TestWindow(QtGui.QMainWindow):
    def __init__( self, parent == None ):
        super(TestWindow, self).__init__(parent)

        # create the ui (or load it)
        self.__editor = testwidget.TestWidget(self)
        self.setCentralWidget(self.__editor)

        # create connections
        self.__editor.textSaved.connect(self.showMessage)

    def showMessage( self, message ):
        QtGui.QMessageBox.information(self, 'Message', message)

所以,你可以看到,与其像“当我在TestWidget中点击按钮时,我想在TestWindow中显示一条消息”这样考虑并显式地连接这两个方法,你要公开一个信号,当用户执行操作时TestWidget将会发出该信号,然后将该信号连接到TestWindow的showMessage插槽。这样,你的小部件变得更加独立,而更多的是如何连接每个驱动应用程序事件的问题。
我本可以在TestWidget的emitTextSaved方法中做一些类似于self.parent().showMessage(self.__edit.toPlainText())的事情来直接调用该方法,但这不是一个好的设计。

谢谢 - 我需要一些时间来处理这个,但是这个想法似乎相当简单明了。我看到TestWidget发出的信号,但我不知道TestWindow是如何接收信息的。我会输入所有的代码并从那里弄清楚... - tom stratton
这行代码:self.__editor.textSaved.connect(self.showMessage) 是从textSaved信号到showMessage槽创建连接。它使用了PyQt的新风格连接语法。 - Eric Hulser
所以,在生成信号的模块(或类)中不连接信号,而是在第二个类中引用后将其连接到槽... 不是很直观 :-( 我真的很难理解,但它正在逐渐变得清晰。再次感谢! - tom stratton
实际上发生的是,当信号被发射时,它会通过并运行每个已注册的方法。您可以连接任意数量的方法以在信号发射时运行。因此,将连接视为注册回调方法。 - Eric Hulser
Eric - 我真正想要实现的是让一个窗口/小部件能够影响另一个窗口/小部件。在这个例子中,您将第二个小部件加载到TestWindow类中。如何在不“包含”彼此的对象之间建立连接? - tom stratton
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接