Tem*_*ayo 12 python dependency-properties pyqt pyside
我是PySide/PyQt的新手,我来自C#/ WPF.我已经在这个主题上搜索了很多但似乎并没有出现好的答案.
我想问有没有办法可以将QWidget绑定/连接到局部变量,从而每个对象在更改时自行更新.
示例:如果我有一个QLineEdit并且我self.Name在给定的类中有一个局部变量,我该如何绑定这两个,从而在textChanged()触发a时或简单地说QLineEdit变量上的文本更改被更新,同时,当变量是更新了QLineEditget更新,无需调用任何方法.
在C#中,有依赖项属性,转换器和Observable集合用于处理此函数的列表.
如果有人能给出好的榜样,我会很高兴的
Dan*_*ank 20
你在这里要求两件不同的东西.
self.name订阅一个更改QLineEdit.QLineEdit订阅普通python对象上的更改self.name.订阅更改QLineEdit很容易,因为这就是Qt信号/插槽系统的用途.你就是这样做的
def __init__(self):
...
myQLineEdit.textChanged.connect(self.setName)
...
def setName(self, name):
self.name = name
Run Code Online (Sandbox Code Playgroud)
更棘手的部分是让QLineEdit中的文本在更改时self.name更改.这很棘手,因为self.name它只是一个普通的python对象.它对信号/插槽一无所知,而且python没有内置系统来以C#的方式观察对象的变化.你仍然可以做你想做的事.
最简单的方法是制作self.name一个房产.以下是链接文档的简要示例(为了清晰起见而进行了修改)
class Foo(object):
@property
def x(self):
"""This method runs whenever you try to access self.x"""
print("Getting self.x")
return self._x
@x.setter
def x(self, value):
"""This method runs whenever you try to set self.x"""
print("Setting self.x to %s"%(value,))
self._x = value
Run Code Online (Sandbox Code Playgroud)
您可以添加一行来更新QLineEditsetter方法.这样,每当修改任何值时x,QLineEdit都会更新.例如
@name.setter
def name(self, value):
self.myQLineEdit.setText(value)
self._name = value
Run Code Online (Sandbox Code Playgroud)
请注意,名称数据实际上保存在一个被调用的属性中,_name因为它必须与getter/setter的名称不同.
所有这些的弱点在于您无法在运行时轻松更改此观察者模式.要做到这一点,你需要一些非常像C#提供的东西.python中的两个C#样式观察器系统是obsub,我观察了自己的项目.我在自己的pyqt项目中使用了观察并取得了很大的成功.请注意,PyPI上观察到的版本落后于github上的版本.我推荐github版本.
如果你想以最简单的方式自己做,你会做这样的事情
import functools
def event(func):
"""Makes a method notify registered observers"""
def modified(obj, *arg, **kw):
func(obj, *arg, **kw)
obj._Observed__fireCallbacks(func.__name__, *arg, **kw)
functools.update_wrapper(modified, func)
return modified
class Observed(object):
"""Subclass me to respond to event decorated methods"""
def __init__(self):
self.__observers = {} #Method name -> observers
def addObserver(self, methodName, observer):
s = self.__observers.setdefault(methodName, set())
s.add(observer)
def __fireCallbacks(self, methodName, *arg, **kw):
if methodName in self.__observers:
for o in self.__observers[methodName]:
o(*arg, **kw)
Run Code Online (Sandbox Code Playgroud)
现在,如果您只是子类Observed,则可以在运行时向所需的任何方法添加回调.这是一个简单的例子:
class Foo(Observed):
def __init__(self):
Observed.__init__(self)
@event
def somethingHappened(self, data):
print("Something happened with %s"%(data,))
def myCallback(data):
print("callback fired with %s"%(data,))
f = Foo()
f.addObserver('somethingHappened', myCallback)
f.somethingHappened('Hello, World')
>>> Something happened with Hello, World
>>> callback fired with Hello, World
Run Code Online (Sandbox Code Playgroud)
现在,如果您.name按上述方法实现该属性,则可以使用@event它来装饰setter 并订阅它.
| 归档时间: |
|
| 查看次数: |
6781 次 |
| 最近记录: |