2016-02-26 172 views
1

我嘗試創建一個GUI用於顯示蟒蛇512個值的列表0/255更新而QListView從另一個線程(pyqt5)更新Python列表

很簡單與PyQt的設置一個QListWidget或而QListView顯示此種類列表

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_()) 

我可以創建一個按鈕來發送隨機值。沒有延遲,一切都很好。

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_()) 

我的問題是,我用於偵聽新幀的庫需要在一個單獨的線程。我創建一個線程來偵聽列表的更新。但是我無法設法在每次更改值時更新我的​​QListView/QListWidget。 只有當我點擊小部件本身時,纔會更新小部件。

我嘗試了所有在論壇中找到的內容,但無法使其工作。我嘗試使用dataChanged.emit的信號,甚至是一個(醜陋的)全局信號。但是我的觀點並沒有更新價值。

下面是全球醜陋的最新代碼。

如果有人能幫助我這一點。

歡呼聲!

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_()) 

回答

0

您需要告訴模型基礎數據已更改,以便它可以更新視圖。這可以用自定義的信號來完成,像這樣:

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() 

然後連接到模型是這樣的:

my_process = SpecialProcess() 
    my_process.universeChanged.connect(self.model.layoutChanged.emit)