2014-08-29 83 views
0

因此,我有一個包含小部件的GUI,它在數據庫中查找變量的值,並以與kv對相同的方式顯示變量名稱和當前值兩個QLabel彼此相鄰,並稱他們爲DisplayItemWidget。然後,我在另一個窗口小部件中堆疊了一堆這些DisplayItemWidget,我稱其爲CellContainerWidget,並且我在網格中有一堆這樣的小部件,這樣我可以在變化時跟蹤多個變量分組。所有小部件查詢的數據庫都在不斷更新,我希望我的GUI能夠更新每個人的更新,每秒鐘更新一次。但我不知道該怎麼做。我嘗試使用QTimer將定時器事件發送到MainWindow,但這不起作用。所以我想知道什麼是體系結構應該是每秒更新內部小部件。如何每秒鐘更新容器小部件中的標籤小部件

我的代碼的一個精簡版是在這裏:

from PyQt4.QtGui import * 
    from PyQt4.QtCore import * 
    import sys 
    import random 

    def main(): 
     app = QApplication(sys.argv) 
     db = Database() 

     ########## instantiate fake data 
     cell_list = [] 
     taglist = ['ground_tlm', 'state_tlm'] 
     counter = 0 
     for tag in taglist: 
      display_list = [] 
      display_name = tag.split('_')[0] + ' stuff' 
      for i in range(int((random.random()*5)+1)): 
       db.update([tag, 'var-%i' % i, 'float', str(random.random())]) 
       widget = DisplayItemWidget(tag, 'var-%i' % i, db) 
       display_list.append(widget) 
      ccw = CellContainerWidget(display_list, display_name, counter, 0) 
      counter += 1 
      cell_list.append(ccw) 

     taglist = ['random_tlm', 'up_tlm'] 
     counter = 0 
     for tag in taglist: 
      display_list = [] 
      display_name = tag.split('_')[0] + ' stuff' 
      for i in range(int((random.random()*5)+1)): 
       db.update([tag, 'var-%i' % i, 'float', str(random.random())]) 
       widget = DisplayItemWidget(tag, 'var-%i' % i, db) 
       display_list.append(widget) 
      ccw = CellContainerWidget(display_list, display_name, counter, 1) 
      counter += 1 
      cell_list.append(ccw) 
     ########## 

     mw = MainWindow(cell_list, db) 
     mw.show() 
     timer = QBasicTimer() 
     timer.start(500, mw) 
     sys.exit(app.exec_()) 


    class DisplayItemWidget(QWidget): 

     def __init__(self, tag, var_name, db): 
      super(DisplayItemWidget, self).__init__() 
      self.layout = QHBoxLayout() 
      self.label1 = QLabel() 
      self.label2 = QLabel() 
      self.tag = tag 
      self.var_name = var_name 
      self.db = db 
      self.init_ui() 

     def init_ui(self): 
      self.label1.setText(self.tag + ': ' + self.var_name) 

      self.label1.setAlignment(Qt.AlignCenter) 
      self.label1.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) 
      self.layout.addWidget(self.label1) 

      val = self.db.get_val(self.tag, self.var_name) 
      if val is not None: 
       self.label2.setText(val) 
       self.label2.setText(val) 
      self.label2.setAlignment(Qt.AlignCenter) 
      self.label2.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) 
      self.layout.addWidget(self.label2) 

      self.layout.setSpacing(10) 
      self.setLayout(self.layout) 
      self.setWindowTitle("Display Item Widget") 

     def update_value(self): 
      val = self.db.get_val(self.tag, self.var_name) 
      if val is not None: 
       self.label2.setText(val) 


    class CellContainerWidget(QWidget): 

     def __init__(self, display_list, cell_name, col_index, row_index): 
      super(CellContainerWidget, self).__init__() 
      self.layout = QVBoxLayout() 
      self.cell_name_label = QLabel() 
      self.cell_name_label.setText(cell_name) 
      self.display_list = display_list 
      self.col_index = col_index 
      self.row_index = row_index 
      self.init_ui() 

     def init_ui(self): 
      self.cell_name_label.setAlignment(Qt.AlignCenter) 
      self.cell_name_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) 
      self.layout.addWidget(self.cell_name_label) 

      for widget in self.display_list: 
       widget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) 
       self.layout.addWidget(widget) 

      self.layout.setSpacing(0) 
      self.setLayout(self.layout) 
      self.setWindowTitle("Cell Item Widget") 

     def get_widgets(self): 
      return self.display_list 


    class MainWindow(QWidget): 
     def __init__(self, cell_list, db): 
      super(MainWindow, self).__init__() 
      self.layout = QGridLayout() 
      self.cell_list = cell_list 
      self.db = db 
      self.init_ui() 

     def init_ui(self): 
      for cell in self.cell_list: 
       cell.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) 
       self.layout.addWidget(cell, cell.col_index, cell.row_index) 

      self.layout.setSpacing(0) 
      self.setLayout(self.layout) 
      self.setWindowTitle("Main Window Widget") 

     def update_gui(self, event): 

      ########## Mock out update to first column 
      print self.db.print_contents() 
      taglist = ['ground_tlm', 'state_tlm'] 
      for tag in taglist: 
       for i in range(int((random.random()*5)+1)): 
        self.db.update([tag, 'var-%i' % i, 'float', str(random.random())]) 
      ########## 

      for cell in self.cell_list: 
       for widget in cell.get_widgets(): 
        widget.update_value() 


    class Database(): 
     def __init__(self): 
      self.telemetry_types = { 
       'state_tlm': {'var-1': ('int', '0'), } # Example of how this will be populated 
      } 

     def get_var_table(self, tlm_type): 
      return self.telemetry_types.get(tlm_type, None) 

     def update(self, parsed_data): 
      tlm_type, var_name, var_type, datum = parsed_data 
      if tlm_type in self.telemetry_types: 
        self.telemetry_types[tlm_type][var_name] = (var_type, datum) 
      else: 
       self.telemetry_types[tlm_type] = { 
        var_name: (var_type, datum), 
       } 

     def get_val(self, tlm_type, var_name): 
      if tlm_type in self.telemetry_types: 
       if var_name in self.telemetry_types[tlm_type]: 
        return self.telemetry_types[tlm_type][var_name][1] 
       else: 
        return None 
      else: 
       return None 

     def print_contents(self): 
      print self.telemetry_types 

     def get_keys(self): 
      return self.telemetry_types.keys() 

    if __name__ == '__main__': 
     main() 

只更新一次,然後永不復還。事件計時器甚至沒有被mw註冊。我覺得我錯失了一些根本性的錯誤。

回答

2

您沒有正確實例化您的計時器。

當前,您將對象mw傳遞給QBasicTimer,但該對象尚未寫入來處理Timer事件。總之,它不知道它應該調用update_gui(爲什麼不是嗎?這是你創建的任意命名的方法!)

相反,我會建議構建一個計時器,如下所示,使用QTimer類,而比QBasicTimer

timer = QTimer(mw) 
timer.timeout.connect(mw.update_gui) 
timer.start(500) 

這就產生了一個QTimer,連接timeout信號到update_gui槽並啓動定時器(以500毫秒的超時)。

請注意,您還需要將MainWindow.update_gui的簽名更改爲不包含event變量。所以它應該看起來像def update_gui(self):

+0

這是有道理的。我這樣做的原因是因爲我看到一個使用計時器事件來更新日期時間小部件的例子。但是,我明白這樣做沒有任何意義。謝謝。 – 2014-09-02 16:17:52