我对PySide/PyQt很陌生,我来自C#/WPF。我在谷歌上搜索了很多关于这个话题的信息,但似乎没有一个好的答案出现。
我想问的是,有没有一种方法可以将QWidget绑定/连接到一个局部变量,从而每个对象在发生更改时更新自己。
示例:如果在给定的类中有一个QLineEdit
,并且有一个局部变量self.Name
,那么如何绑定这两个变量,即当textChanged()
被触发时,或者简单地说QLineEdit
上的文本更改时,变量将被更新,同时,当变量被更新时,将在不调用任何方法的情况下更新QLineEdit
。
在C#中,有一个依赖属性,其中包含处理此函数的转换器和列表的可观察集合。
如果有人能以身作则,我会很高兴的
你在这里要两样东西。
self.name
订阅QLineEdit
上的更改。QLineEdit
订阅普通python对象上的更改self.name
。订阅
QLineEdit
上的更改很容易,因为这就是Qt信号/时隙系统的用途。你就是喜欢这样更棘手的部分是让QLineEdit中的文本在
self.name
更改时更改。这很棘手,因为self.name
只是一个普通的python对象。它对信号/插槽一无所知,而且python没有一个内置的系统,可以像C#那样观察对象的变化。但你仍然可以做你想做的事。使用带有Python属性特性的getter/setter
最简单的事情就是把
self.name
变成Property。以下是链接文档中的一个简短示例(为了清楚起见,已修改)您可以添加一行来更新setter方法中的
QLineEdit
。这样,只要有任何东西修改了x
的值,就会更新QLineEdit
。例如注意,名称数据实际上被保存在名为
_name
的属性中,因为它必须与getter/setter的名称不同。使用真正的回调系统
所有这些的缺点是,您不能在运行时轻松地更改这个观察者模式。要做到这一点,你需要一些真正像C提供的东西。python中的两个C风格的观察者系统是obsub和我自己的项目observed。 我在自己的pyqt项目中使用了observated,并取得了很大的成功。 注意,PyPI上观察到的版本落后于github上的版本。我推荐github版本。
创建自己的简单回调系统
如果你想用最简单的方法自己做,你会做这样的事情
现在,如果您只是子类
Observed
,那么可以在运行时向任何方法添加回调。下面是一个简单的例子:现在,如果实现了如上所述的
.name
属性,就可以用@event
装饰setter并订阅它。我已经为一个pyqt项目设计了一个小型的通用双向绑定框架。这是:https://gist.github.com/jkokorian/31bd6ea3c535b1280334#file-pyqt2waybinding
下面是一个如何使用它的例子(也包括在要点中):
模型(非gui)类
QWidget(gui)类
Observer
实例绑定到QSpinBox
实例的valueChanged
信号,并使用setValue方法更新该值。它还了解如何绑定到python属性,假设绑定端点实例上有相应的propertyNameChanged(命名约定)pyqtSignal。更新我对它更感兴趣,并为它创建了一个合适的存储库:https://github.com/jkokorian/pyqt2waybinding
要安装:
另一种方法是使用像pypubsub这样的发布-订阅库。您可以让QLineEdit订阅您选择的主题(例如,“event.name”),并且每当代码更改self.name时,您就发送该主题的消息(选择event来表示正在更改的名称,例如“flower.name changed”)。其优点是,给定主题的所有侦听器都将被注册,QLineEdit不需要知道它所侦听的具体名称。这个松耦合对你来说可能太松了,所以它可能不合适,但我只是把它作为另一个选择扔掉。
另外,有两个问题是不是特定于发布-订阅策略(即。,另外,对于其他答案中提到的obsub etc):如果您侦听QLineEdit,它设置self.name,通知侦听器self.name已更改,最后调用QLineEdit settext等,则可能会出现无限循环。您需要一个保护,或者检查self.name是否已经具有来自QLineEdit的值,则不执行任何操作;类似地,在QLineEdit如果显示的文本与self.name的新值相同,则不要设置它,这样就不会生成信号。
相关问题 更多 >
编程相关推荐