Qt 基于事件驱动编程。通常,当您开始构建小部件时,您想要做的是通过随后处理的信号向接收器小部件提供信息。您不希望显式地让子小部件知道或要求调用父小部件上的方法(并非总是如此,但最好尽可能避免)。
为了方便起见,我将发布一些没有 UI 文件的示例,但假设您可以使用设计器构建相同的小部件并让它以相同的方式工作......
测试小部件.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())
测试窗口.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()) 的操作来直接调用该方法——但这不是一个好的设计。