嗨我有一个简单的GUI,如下面的2个按钮。我编写了一个方法,一旦单击按钮,就会更改按钮上的文本。我想使方法模块化和通用,以便将方法应用于任何按钮而无需重写。在下面的示例中,如何在不为其定义新方法的情况下将printWow()方法应用于按钮2?
import sys
from PyQt4.Qt import *
class MainWindow(QMainWindow):
def __init__(self, *args):
QMainWindow.__init__(self, *args)
self.cw = QWidget(self)
self.setCentralWidget(self.cw)
self.btn1 = QPushButton("Click me", self.cw)
self.btn1.setGeometry(QRect(50, 50, 100, 30))
self.btn1.clicked.connect(self.printWow)
self.btn2 = QPushButton("Click me", self.cw)
self.btn2.setGeometry(QRect(50, 20, 100, 30))
self.btn2.clicked.connect(self.printWow)
def printWow(self):
self.btn1.setText("WoW")
if __name__ == "__main__":
app = QApplication(sys.argv)
myapp = MainWindow()
myapp.show()
sys.exit(app.exec_())
答案 0 :(得分:1)
您可以使用sender()
方法确定点击了哪个按钮。
如果在由信号激活的插槽中调用,则返回指向发送信号的对象的指针;否则它返回0.指针仅在执行从该对象的线程上下文调用此函数的槽期间有效。
如果发件人被销毁,或者插槽与发件人的信号断开连接,此功能返回的指针将变为无效。
但是文档中有一个重要的警告,这会与你的帖子标题冲突:
警告:此功能违反了面向对象的模块化原则。但是,当许多信号连接到单个插槽时,访问发送方可能很有用。
你可以这样使用sender()
:
def printWow(self):
self.sender().setText("WoW")
答案 1 :(得分:1)
基本上,使功能更通用"意味着识别不同用例中的变体和不变量。在您的示例中,变体将是您要在其上调用setText()
并最终调用文本本身的对象,因此您的"泛型"功能看起来像:
def printText(self, target, text="wow"):
target.setText(text)
然后,因为你不能将这些参数传递给connect()
(至少让我们假设这是为了我们的例子),你需要将对泛型函数的引用和参数,可以在没有参数的情况下调用。这是"部分评估"的例子,并且在其最简单的形式中,它只需要lambda
:
class MainWindow(QMainWindow):
def __init__(self, *args):
QMainWindow.__init__(self, *args)
self.cw = QWidget(self)
self.setCentralWidget(self.cw)
self.btn1 = QPushButton("Click me", self.cw)
self.btn1.setGeometry(QRect(50, 50, 100, 30))
self.btn1.clicked.connect(lambda: self.printWow(self.btn1))
self.btn2 = QPushButton("Click me", self.cw)
self.btn2.setGeometry(QRect(50, 20, 100, 30))
self.btn2.clicked.connect(lambda: self.printText(self.btn2, "Yay!"))
def printText(self, target, text="wow"):
target.setText(text)
请注意,在上面的示例中,您不会从额外的复杂性中获得太多收益 - 您也可以将所有内容放在lambda中,即:
self.btn1.clicked.connect(lambda: self.btn1.setText("Wow"))
self.btn2.clicked.connect(lambda: self.btn2.setText("Yay !"))
但我认为你有更复杂的东西......
现在你提到"模块化" (至少在你的标题中)," modular"的真正关键。代码不一定(或至少不仅仅)分解出公共代码,而且主要是将代码拆分为良好的解耦模块,每个模块都有明确且明确的响应性。一个典型的例子是将UI代码与"域"代码 - 完成实际工作的代码,甚至根本不知道UI存在...