如何将数据对象设置为没有setData()方法的widget?

问题描述 投票:0回答:3

我需要将数据对象(类实例)连接到 QLabel widget没有setData()方法。有什么方法可以扩展QLabel,使它支持数据附件?

python pyqt
3个回答
1
投票

我建议采用子类化的方式。虽然@BlackJack的答案也可以,但一般来说,"鸭子打拳""猴子打补丁 "被认为是不好的形式,因为你会给自己带来问题。来自 维基百科

编写不慎或文档不完善的猴子补丁可能会导致问题。

  • 当补丁对被修补的对象做出不再真实的假设时,它们可能会导致升级问题;如果你所改变的产品随着新版本的发布而改变,很可能会破坏你的补丁。出于这个原因,猴子补丁通常是有条件的,并且只有在适当的情况下才会被应用。

  • 如果两个模块试图给同一个方法打猴子补丁,其中一个(以最后运行的那个为准)"赢了",而另一个补丁则没有任何效果,除非猴子补丁是用类似 alias_method_chain 这样的模式写的。

  • 它们在磁盘上的原始源代码和观察到的行为之间产生了差异,这对于不知道补丁存在的人来说,可能会非常混乱。

即使不使用猴子补丁,有些人也认为该功能的可用性有问题,因为在编程语言中使用猴子补丁的能力与对象能力模型所要求的对象之间的强封装是不兼容的。

因此,子类是首选的方法。比如说,类似这样。

class MyLabel(QLabel):
    def __init__(self, *args, **kwargs):
        QLabel.__init__(self, *args, **kwargs)
        self._data = None

    def data(self):
        return self._data

    def setData(self, data):
        self._data = data

这样就能与其他类的Qt语法相匹配。

你也可以扩展它来支持存储多个角色的数据(就像一些其他的Qt类一样

class MyLabel(QLabel):
    def __init__(self, *args, **kwargs):
        QLabel.__init__(self, *args, **kwargs)
        self._data = {}

    def data(self, role = Qt.DisplayRole):
        if role in self._data:
            return self._data[role]
        return None

    def setData(self, data, role = Qt.DisplayRole):
        self._data[role] = data

很明显,这只适用于你的Python代码 (Qt不会使用它)。


1
投票

你是否尝试过将数据分配给一个属性?

In [2]: from PyQt4 import QtCore, QtGui

In [3]: import sys

In [4]: app = QtGui.QApplication(sys.argv)

In [5]: label = QtGui.QLabel('Test')

In [6]: label.answer = 42

In [7]: label.answer
Out[7]: 42

0
投票

你可以使用动态的setProperty方法来隐藏Qt对象中的额外信息。

self.myqlabel.setProperty("answer", 42) 

然后再使用属性方法来检索信息。

value = self.myqlabel.property("answer")   

这种技术的另一个好处是... 你可以存储多条数据, 只要把属性字符串改成你想要的任何东西:

self.myqlabel.setProperty("name", "bruno mars") 

不确定,但这可能是Qt5的一个功能?

© www.soinside.com 2019 - 2024. All rights reserved.