2016-09-21 16 views
0

私は100msごとに実行され、GUIを更新するコードを持っています。私はGUIを更新するとき - 私はスレッドを呼び出し、それはターゲット関数を呼び出してボタンを押しています。ターゲット関数は、次のようにpub subを使用してGUIスレッドにメッセージを返します。あなたは私のREADEVENTを見ることができるようにGUIの頻繁な更新WxPYTHON

wx.CallAfter(pub.sendMessage, "READ EVENT", arg1=data, arg2=status_read) # This command line is in my target function 

     pub.subscribe(self.ReadEvent, "READ EVENT") # This is in my GUI file - whihc calls the following function 

def ReadEvent(self, arg1, arg2): 
     if arg2 == 0: 
      self.MessageBox('The program did not properly read data from MCU \n Contact the Program Developer') 
      return 

     else: 
      self.data = arg1 

      self.firmware_version_text_control.Clear() 
      #fwversion = '0x' + ''.join('{:02X}'.format(j) for j in reversed(fwversion)) 
      self.firmware_version_text_control.AppendText(str(SortAndDecode(self.data, 'FwVersion'))) 
      # Pump Model 
      self.pump_model_text_control.Clear() 
      self.pump_model_text_control.AppendText(str(SortAndDecode(self.data, 'ModelName'))) 
      # Pump Serial Number 
      self.pump_serial_number_text_control.Clear() 
      self.pump_serial_number_text_control.AppendText(str(SortAndDecode(self.data, 'SerialNum'))[:10]) # Personal Hack to not to display the AA , AB and A0 
      # Pressure GAIN 
      self.gain_text_control.Clear() 
      self.gain_text_control.AppendText(str(SortAndDecode(self.data, 'PresGain'))) 
      # Pressure OFFSET Offset 
      self.offset_text_control.Clear() 
      self.offset_text_control.AppendText(str(SortAndDecode(self.data, 'PresOffset'))) 
      #Wagner Message: 
      #self.status_text.SetLabel(str(SortAndDecode(self.data, 'WelcomeMsg'))) 
      # PUMP RUNNING OR STOPPED 

      if PumpState(SortAndDecode(self.data, 'PumpState')) == 1: 
       self.led6.SetBackgroundColour('GREEN') 
      elif PumpState(SortAndDecode(self.data, 'PumpState')) == 0: 
       self.led6.SetBackgroundColour('RED') 
      else: 
       self.status_text.SetLabel(PumpState(SortAndDecode(self.data, 'PumpState'))) 
      # PUMP RPM 
      self.pump_rpm_text_control.Clear() 
      if not self.new_model_value.GetValue(): 
       self.pump_rpm_text_control.AppendText("000") 
      else: 
       self.pump_rpm_text_control.AppendText(str(self.sheet_num.cell_value(self.sel+1,10)*(SortAndDecode(self.data, 'FrqQ5'))/65536)) 
      # PUMP PRESSURE 
      self.pressure_text_control.Clear() 
      self.pressure_text_control.AppendText(str(SortAndDecode(self.data, 'PresPsi'))) 
      # ON TIME -- HOURS AND MINUTES --- EDITING IF YOU WANT 
      self.on_time_text_control.Clear() 
      self.on_time_text_control.AppendText(str(SortAndDecode(self.data, 'OnTime'))) 
      # JOB ON TIME - HOURS AND MINUTES - EDITING IF YOU WANT 
      self.job_on_time_text_control.Clear() 
      self.job_on_time_text_control.AppendText(str(SortAndDecode(self.data, 'JobOnTime'))) 
      # LAST ERROR ----- RECHECK THIS AGAIN 
      self.last_error_text_control.Clear() 
      self.last_error_text_control.AppendText(str(SortAndDecode(self.data, 'LastErr'))) 
      # LAST ERROR COUNT --- RECHECK THIS AGAIN 
      self.error_count_text_control.Clear() 
      self.error_count_text_control.AppendText("CHECK THIS") 

は非常に大きいとGUIが正常にすべてのこれらの事を行うのに十分な時間を取ることが時間がかかります。私の問題は、私のGUIがTEXTCTRLの値を更新しているときに応答しなくなることです。何もできません。私はボタンを押したり、データなどを入力することはできません。私の質問は、これを行うためのよりよい方法があるかどうかです。私のGUIは応答しなくなります。すべてのウィジェットがメインのGUIにあるので、これを別のスレッドにどのように置くことができるのか分かりません。しかし、それは100msごとにスレッドを作成し続ける必要もあります。これは恐ろしいことです。どんな提案も大いに役立ちます。

答えて

0

ヒント:

  1. SortAndDecodeはどのくらいかかりますか?結果のstr()はどうですか?それらは、UIスレッドの代わりにワーカースレッドでその処理を保持し、その値をUIスレッドに事前ソートおよびデコードされたものに渡すのに適した候補である可能性があります。

  2. AppendTextの代わりにChangeValueを呼び出すことで、各繰り返しで少し時間を節約できます。なぜ、2つの関数がそれぞれのテキストウィジェットを呼び出すのではなく、それぞれの関数を呼び出すのですか?関数呼び出しは、他のPythonコードと比較してPythonでは比較的高価です。

  3. 最後の繰り返しで送信された同じ値が送信される可能性がある場合は、古い値と一致する新しい値のチェックを追加し、ウィジェットの更新をスキップすると潜在的に多くの時間を節約できます。ウィジェットの値を更新することは、ウィジェットの値を残すことと比べて非常に高価です。

  4. 100msの更新が困難な場合を除いて、150または200を試してみるとよいでしょう。ほとんどの人にとって、毎秒更新回数が少なくて済みます。 100msでどれくらいのテキストを読むことができますか?

  5. UIスレッドよりも多くの更新プログラムで問題が解決しない場合は、pubsubとwx.CallAfter以外の方法を使用することができます。たとえば、ワーカースレッドにデータを受信して​​処理させてから、オブジェクトをQueue.Queueに追加してからwx.WakeUpIdle()を呼び出すことができます。 UIスレッドでは、EVT_IDLEイベントハンドラを使用してキューをチェックし、最初のアイテムがあればそれをキューから取り出し、ウィジェットをそのデータで更新します。これにより、保留中のイベントリストにあまりにも多くのコールのイベントが氾濫しないようにすることができます。また、アイテムが多すぎるとデータキューからアイテムを削除するなどの作業を行うこともできます。

+0

興味深い回答。私はポイント3と5にもっと興味を持っています。ポイント3 - 実行するコードがそれ以上ありませんか?プロセスをより遅くするか? ポイント5:私に例を教えてください。私は1か月前のようにキューを試してみましたが、192個の長さの配列の1つの要素しか与えていないので、非常にうまく失敗しました。 wx.WakeupIdleを使用して私に例を挙げていただければ幸いです –

関連する問題