Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python pyqt:动态更新动态创建的小部件的属性_Python_Qt_Qt4_Pyqt_Pyqt4 - Fatal编程技术网

Python pyqt:动态更新动态创建的小部件的属性

Python pyqt:动态更新动态创建的小部件的属性,python,qt,qt4,pyqt,pyqt4,Python,Qt,Qt4,Pyqt,Pyqt4,我试图找到一种方法,根据前面小部件中动态设置的属性,更新动态创建的小部件(可以删除)中的标签 有没有一种方法可以自动地、动态地将pyqt对象链接到其他小部件的属性,这样当我在任何地方更改一个值时,该对象就会自动更新 示例:对象“a”具有属性开始,条和结束条给定,前一个对象取开始(如果没有,则取1),计算结束。对象“b”从a获取其开始。结束,依此类推 class myclass(object): def __init__(self, referrer=None, value=1): s

我试图找到一种方法,根据前面小部件中动态设置的属性,更新动态创建的小部件(可以删除)中的标签

有没有一种方法可以自动地、动态地将pyqt对象链接到其他小部件的属性,这样当我在任何地方更改一个值时,该对象就会自动更新

示例:对象“a”具有属性
开始
结束
<代码>条给定,前一个对象取
开始
(如果没有,则取1),计算
结束
。对象“b”从
a获取其
开始
。结束
,依此类推

class myclass(object):
  def __init__(self, referrer=None, value=1):
    self.referrer=referrer
    self.value=value

  def _get_start(self):
    if not self.referrer:
      return 1
    else:
      return self.referrer.end+1

  def _get_end(self):
    return self.start+self.value-1

  start=property(_get_start)
  end=property(_get_end)

def create(value=1):
  if not vList:
    ref=None
  else:
    ref=vList[-1]
  val=myclass(ref, value)
  vList.append(val)

def showList():
  for i in vList:
    print 'item: %d\tstart: %d\tend: %d' % (vList.index(i),i.start, i.end)

vList=[]
如果我调用create()三次,showList()将显示:

item: 0 start: 1        end: 1
item: 1 start: 2        end: 2
item: 2 start: 3        end: 3
如果我将vList[0]的值更改为3:

item: 0 start: 1        end: 3
item: 1 start: 4        end: 4
item: 2 start: 5        end: 5
当我需要在gui()中更新这些值时,问题就出现了:每个水平小部件都有一个标签,显示
开始
的属性,一个用于
的旋转框,以及一个用于
结束
的标签,只要任何旋转框值发生变化,每个后续小部件都应该根据其先前的小部件更新其
开始
结束
属性,并在相关标签中显示它们。 此外,当任何小部件被删除时,所有后续小部件都应该重新计算每个属性

使用getter/setter在小部件的下一个实例的标签中设置值显然不能像我所需要的那样工作,因为当我更改任何
x.value
时,以下实例的
start
end
实际上只有在调用时才会更新。 我可以将每个新的小部件连接到以前的小部件(使用
valueChanged()
),或者创建一个函数来查找后续小部件并更新其属性,但这不是一个好的解决方案

由于我几乎是python新手(最重要的是:我不是程序员),我认为我忽略了一些关于以更好、最干净的方式“连接”变量的内容(可能与信号或线程有关?)

假设这些小部件实际上是另一个“主”小部件的子小部件,该小部件将具有类似的属性:
start
取自其先前的主小部件(如果有),
bar
是每个子小部件中所有
bar
的总和,
end
将再次是
start+bar-a

谢谢


(我希望你能理解我的意思,我的英语并不完美,而且,由于我不是程序员,我的术语并不总是正确的)

我无法从你的问题中找到适用的用例,但这里有一个使用Qt信号插槽的可能解决方案:

# -*- coding: utf-8 -*-
import functools

from PyQt4 import QtGui, QtCore


class ObservableVariable(QtCore.QObject):
    """ Represents variable with value, when value changes it emits
    signal: changed(new_value)
    """
    changed = QtCore.pyqtSignal(object)

    def __init__(self, initial_value=0):
        super(ObservableVariable, self).__init__()
        self._value = initial_value

    def get_value(self):
        return self._value

    def set_value(self, new_val):
        self._value = new_val
        self.changed.emit(new_val)

    value = property(get_value, set_value)

    def __str__(self):
        return str(self.value)

    # it can support more operators if needed
    def __iadd__(self, other):
        self.value += other
        return self

    def __isub__(self, other):
        self.value -= other
        return self


class MyClass(object):
    def __init__(self, referrer=None, value=1):
        self.referrer = referrer
        self.value = ObservableVariable(value)
        self._initial_value = value
        if referrer:
            # propagate referrer changes to subscribers
            referrer.value.changed.connect(
                lambda x: self.value.changed.emit(self.value.value)
            )

    @property
    def start(self):
        if not self.referrer:
            return self.value.value
        return self.referrer.end + 1

    @property
    def end(self):
        return self.start + self.value.value - 1


class GuiExample(QtGui.QWidget):
    def __init__(self):
        super(GuiExample, self).__init__()
        self.values = []
        layout = QtGui.QVBoxLayout(self)
        obj = None
        for i in range(5):
            obj = MyClass(obj, i)
            self.values.append(obj)
            # create gui elements
            hlayout = QtGui.QHBoxLayout()
            spinbox = QtGui.QSpinBox()
            spinbox.setValue(obj.value.value)
            start_label = QtGui.QLabel()
            end_label = QtGui.QLabel()
            hlayout.addWidget(start_label)
            hlayout.addWidget(spinbox)
            hlayout.addWidget(end_label)
            layout.addLayout(hlayout)

            # function called on value change
            def update_start_end(instance, start_label, end_label):
                start_label.setText(str(instance.start))
                end_label.setText(str(instance.end))

            action = functools.partial(update_start_end, obj, start_label,
                                       end_label)
            action()  # set initial start end text to labels
            # connect signals to gui elements
            obj.value.changed.connect(action)
            spinbox.valueChanged.connect(obj.value.set_value)
            obj.value.changed.connect(spinbox.setValue)
        layout.addWidget(QtGui.QPushButton('test',
                                           clicked=self.test_modification))

    def test_modification(self):
        self.values[1].value += 1


app = QtGui.QApplication([])
gui = GuiExample()
gui.show()

app.exec_()

你的问题很详细。很难确定你需要什么帮助。试着把它提炼成一个你遇到问题的用例,从你的问题开始,然后演示一个例子。我很害怕,对不起。我要把它重写得更好。谢谢。哇,看起来像我要找的。花了一点时间才理解您是如何分配推荐人的(没有意识到
obj
的分配顺序),但现在我已经了解了一切。现在我必须决定是否要手动分配每一个新的引用者(当我在列表的中间删除或插入小部件),但也许我可以找到一种方法来使用“<代码>值< /Cord>列表”自动连接它们。非常感谢你!