首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用从另一个线程更新的python列表更新QlistView (pyqt5)

使用从另一个线程更新的python列表更新QlistView (pyqt5)
EN

Stack Overflow用户
提问于 2016-02-26 14:57:00
回答 1查看 1.8K关注 0票数 1

我尝试创建一个GUI来显示python一个512值的列表0/255

使用PyQt可以很简单地设置一个QListWidget或QListView来显示这种列表

代码语言:javascript
复制
from sys import argv, exit
from PyQt5.QtWidgets import QListWidgetItem, QListWidget, QApplication


class Universe(QListWidget):
    """This is a class for a DMX Universe of 512 dimmers"""
    def __init__(self):
        super(Universe, self).__init__()
        for i in range(512):
            item = QListWidgetItem('dimmer n° '+str(i+1)+' : 0')
            self.addItem(item)

if __name__ == "__main__":
  app = QApplication(argv)
  list_widget = Universe()
  list_widget.show()
  exit(app.exec_())

我可以创建一个按钮来发送随机值。没有延迟,一切都很好。

代码语言:javascript
复制
    from random import randrange
    from sys import argv, exit
    from PyQt5.QtWidgets import QListWidgetItem, QListWidget, QApplication, QGroupBox, QVBoxLayout, QPushButton


    class DisplayGroup(QGroupBox):
        """This is a group of widgets to display"""
        def __init__(self):
            super(DisplayGroup, self).__init__()
            # create a vertical layout
            vbox = QVBoxLayout()
            # create an universeand and add it to the layout
            universe = Universe()
            self.universe = universe
            vbox.addWidget(universe)
            # create a button to make some noise
            button = QPushButton('make some noise')
            vbox.addWidget(button)
            button.released.connect(self.make_some_noise)
            # set the layout on the groupbox
            vbox.addStretch(1)
            self.setLayout(vbox)

        def make_some_noise(self):
            self.universe.update([randrange(0, 101, 2) for i in range(512)])


    class Universe(QListWidget):
        """This is a class for a DMX Universe of 512 dimmers"""
        def __init__(self):
            super(Universe, self).__init__()
            for index in range(512):
                item = QListWidgetItem('dimmer n° '+str(index+1)+' : 0')
                self.addItem(item)

        def update(self, data):
            for index, value in enumerate(data):
                item = self.item(index)
                item.setText('dimmer n° '+str(index+1)+' : '+str(value))



    if __name__ == "__main__":
      app = QApplication(argv)
      group_widget = DisplayGroup()
      group_widget.show()
      exit(app.exec_())

我的问题是,用于侦听新帧的lib必须位于一个单独的线程中。我创建一个线程来侦听列表的更新。但是,每次值更改时,我都无法更新我的QListView / QListWidget。只有当我单击小部件本身时,小部件才会更新。

我尝试了我在论坛上发现的一切,但我无法让它发挥作用。我试图为dataChanged.emit甚至是一个(丑陋的)全局使用signal。但是在我的视图中没有更新这个值。

这是最新的代码与丑陋的全球。

如果有人能在这点上帮我。

干杯!!

代码语言:javascript
复制
    from random import randrange
    from time import sleep
    from sys import argv, exit
    from PyQt5.QtCore import QThread, QAbstractListModel, Qt, QVariant
    from PyQt5.QtWidgets import QListView, QApplication, QGroupBox, QVBoxLayout, QPushButton

    universe_1 = [0 for i in range(512)]

    class SpecialProcess(QThread):
        def __init__(self):
            super(SpecialProcess, self).__init__()
            self.start()

        def run(self):
            global universe_1
            universe_1 = ([randrange(0, 101, 2) for i in range(512)])
            sleep(0.1)
            self.run()


    class Universe(QAbstractListModel):
        def __init__(self, parent=None):
            super(Universe, self).__init__(parent)

        def rowCount(self, index):
            return len(universe_1)

        def data(self, index, role=Qt.DisplayRole):
            index = index.row()
            if role == Qt.DisplayRole:
                try:
                    return universe_1[index]
                except IndexError:
                    return QVariant()
            return QVariant()


    class Viewer(QGroupBox):
        def __init__(self):
            super(Viewer, self).__init__()
            list_view = QListView()
            self.list_view = list_view
            # create a vertical layout
            vbox = QVBoxLayout()
            universe = Universe()
            vbox.addWidget(list_view)
            # Model and View setup
            self.model = Universe(self)
            self.list_view.setModel(self.model)
            # meke a process running in parallel 
            my_process = SpecialProcess()
            # set the layout on the groupbox
            vbox.addStretch(1)
            self.setLayout(vbox)


    if __name__ == "__main__":
      app = QApplication(argv)
      group_widget = Viewer()
      group_widget.show()
      exit(app.exec_())
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-26 19:34:42

您需要告诉模型底层数据已经更改,以便它可以更新视图。这可以通过自定义信号来完成,如下所示:

代码语言:javascript
复制
from PyQt5.QtCore import pyqtSignal

universe_1 = [0 for i in range(512)]

class SpecialProcess(QThread):
    universeChanged = pyqtSignal()

    def __init__(self):
        super(SpecialProcess, self).__init__()
        self.start()

    def run(self):
        universe_1[:] = [randrange(0, 101, 2) for i in range(512)]
        self.universeChanged.emit()
        sleep(0.1)
        self.run()

然后连接到模型,如下所示:

代码语言:javascript
复制
    my_process = SpecialProcess()
    my_process.universeChanged.connect(self.model.layoutChanged.emit)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35654950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档