2014-08-29 58 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