ost*_*ysz 5 python user-interface signals pyside
有没有简单或优雅的方法来区分PySide/PyQt中的许多相同类型的信号源?
我正在学习PySide.我编写了简单的应用程序,它将两个不同的QLineEdit()对象相乘.结果显示在第三个QLineEdit中.
乘法器和被乘数QLineEdit.textChanged()信号连接到一个方法(TxtChanged).在这种方法中,我必须区分信号源.经过一些试验后,我找到了一些基于占位符文本的解决方法(下面4行"还有另一种方法吗?"我的代码中的评论)
码:
import sys
from PySide import QtGui, QtCore
class myGUI(QtGui.QWidget):
def __init__(self, *args, **kwargs):
QtGui.QWidget.__init__(self, *args, **kwargs)
self.multiplier = 0
self.multiplicand = 0
self.myGUIInit()
def myGUIInit(self):
# input forms
a1_label = QtGui.QLabel("a1")
a1_edit = QtGui.QLineEdit()
a1_edit.setPlaceholderText("a1")
a2_label = QtGui.QLabel("a2")
a2_edit = QtGui.QLineEdit()
a2_edit.setPlaceholderText("a2")
# output form
a1a2_label = QtGui.QLabel("a1*a2")
self.a1a2_edit = QtGui.QLineEdit()
self.a1a2_edit.setReadOnly(True)
# forms events
a1_edit.textChanged.connect(self.TxtChanged)
a2_edit.textChanged.connect(self.TxtChanged)
# grid
grid = QtGui.QGridLayout()
grid.setSpacing(10)
grid.addWidget(a1_label,1,0)
grid.addWidget(a1_edit,1,1)
grid.addWidget(a2_label,2,0)
grid.addWidget(a2_edit,2,1)
grid.addWidget(a1a2_label,3,0)
grid.addWidget(self.a1a2_edit,3,1)
self.setLayout(grid)
self.setGeometry(100,100,200,200)
self.setWindowTitle("a*b")
self.show()
def TxtChanged(self,text):
sender = self.sender()
sender_text = sender.text()
if sender_text == '': sender_text = '0'
# is there another way?
if sender.placeholderText() == 'a1':
self.multiplicand = sender_text
else:
self.multiplier = sender_text
product = int(self.multiplier) * int(self.multiplicand)
print(self.multiplier,self.multiplicand,product)
self.a1a2_edit.setText(str(product))
def main():
app = QtGui.QApplication(sys.argv)
mainWindow = myGUI()
sys.exit(app.exec_())
main()
Run Code Online (Sandbox Code Playgroud)
最好的问候,ostrzysz
您可以使用该functools.partial函数 - 因此将您的信号直接连接到您的方法/函数,而不是连接到python对象,该对象将使用您传递的一些额外数据自动调用您的函数:
from functools import partial
...
....
a1_edit.textChanged.connect(partial(self.TxtChanged, a1_edit))
a2_edit.textChanged.connect(partial(self.TxtChanged, a2_edit))
...
def TxtChanged(self,sender, text):
# and here you have the "sender" parameter as it was filled in the call to "partial"
...
Run Code Online (Sandbox Code Playgroud)
partials是stdlib的一部分,并且非常易读,但是可以使用lambda而不是partial来获得相同的效果 -
a1_edit.textChanged.connect(lambda text: self.TxtChanged(a1_edit, text))
Run Code Online (Sandbox Code Playgroud)
通过这种方式,lambda表达式产生的对象将是一个临时函数,它将使用当前局部变量(单击按钮时)的"self"和"a1_edit"的值,以及名为"text"的变量将由Pyside的回调提供.
在你的代码中最让我烦恼的一件事是你正在使用placeholderText区分。QObjects 还有另一个属性叫它objectName更适合您的任务。而且,您不需要使用sender.text()来获取 的文本QLineEdit。textChanged已经发送了它,因此您将在参数中包含它text。
此外,使用字典而不是两个单独的变量(multiplier和multiplicand)将进一步简化您的代码。
这是更改后的代码:
class myGUI(QtGui.QWidget):
def __init__(self, *args, **kwargs):
QtGui.QWidget.__init__(self, *args, **kwargs)
self.data = {"multiplier": 0,
"multiplicand": 0}
self.myGUIInit()
def myGUIInit(self):
a1_label = QtGui.QLabel("a1")
a1_edit = QtGui.QLineEdit()
a1_edit.setObjectName("multiplicand")
a2_label = QtGui.QLabel("a2")
a2_edit = QtGui.QLineEdit()
a2_edit.setObjectName("multiplier")
# skipped the rest because same
def TxtChanged(self, text):
sender = self.sender()
# casting to int while assigning seems logical.
self.data[sender.objectName()] = int(text)
product = self.data["multiplier"] * self.data["multiplicand"]
print(self.data["multiplier"], self.data["multiplicand"], product)
self.a1a2_edit.setText(str(product))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2351 次 |
| 最近记录: |