2016-08-09 12 views
0

他のモジュールから受け取ったデータに基づいて色を変更する必要がある2つのtkinterキャンバスがあります。基本的には0,1 例:キャンバス1〜ブラック、キャンバス2〜グリーン1、受信した場合は0を受信します。tkinterキャンバスの色が変更されない

データを受信するためにマルチプロセッシングキュー手法を使用しましたが、変更を適用しようとしたときに更新されませんでしたか?私はselfと何かがあると仮定します。ここで

は私のコードスニペットは、次のとおりです。 main.py

import multiprocessing 
from udpsocket import * 
from ui import * 

if __name__ == "__main__": 
    queue = multiprocessing.Queue() 
    ui = multiprocessing.Process(target=uiMain, args=(queue,)) 

    ui.daemon = True 
    ui.start() 
    udpMain(queue) 

udpsocket.py:

import time 
import struct 
import socket 
import ui 

MYPORT = 51506 
MYGROUP_4 = '225.0.0.1' 
MYTTL = 1 # Increase to reach other networks 

def udpMain(queue): 
app = udpsocket(queue) 

class udpsocket(): 
    def __init__(self,queue): 
     print('UDP Socket started') 
     group = MYGROUP_4 
     self.receiver('225.0.0.1',queue) 

    def receiver(self,group,queue): 
     print('Receiver') 
     addrinfo = socket.getaddrinfo(group, None)[0] 

     # Create a socket 
     s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) 
     #.... reuse address, binding, add membership 
     # loop, send data to ui 
       while True: 
     data, sender = s.recvfrom(1500) 
     while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's 
     print (str(sender) + ' ' + str(ord(data))) 
     queue.put(ord(data)) 
     ui.do_something(queue) 

ui.py:

from tkinter import * 
from tkinter import ttk 
import multiprocessing 

def uiMain(queue): 
    app = MainWindow() 
    app.mainloop() 

class MainWindow(Frame): 
    def __init__(self): 
     Frame.__init__(self) 
     self.master.title("Test") 
     self.master.minsize(330, 400) 
     self.grid(sticky=E+W+N+S) 

     modeFrame = Frame(self) 
     modeFrame.pack(side="top", fill="x") 
     self.canvas1 = Canvas(modeFrame, height=25, width=25) 
     self.canvas1.create_oval(5, 5, 20, 20, fill="black", tags="SetupLight") 
     self.canvas1.pack(side="left") 

     self.canvas2 = Canvas(modeFrame, height=25, width=25) 
     self.canvas2.create_oval(5, 5, 20, 20, fill="black", tags="RunLight") 
     self.canvas2.pack(side="left") 

    def changeLight(self,value): 
     print('change light ' + str(value)) 
     if(value): 
      self.canvas1.itemconfig("SetupLight", fill="black") 
      self.canvas2.itemconfig("RunLight", fill="green") 
     else: 
      self.canvas1.itemconfig("SetupLight", fill="green") 
      self.canvas2.itemconfig("RunLight", fill="black") 

def do_something(queue): 
     t = MainWindow() 
     MainWindow.changeLight(t,queue.get()) #is this way of calling is correct?? 

注:私は修正しようとしましたmodeFrameself wh Canvasを作成すると、何も起こりませんでした。

私はMainWindow()を何度も作成していたので、キャンバスが色を変えていないという理由から理解しました。私はユースケースの風景で色を変えるのに役立つ実装が必要です

+0

は、なぜあなたはそれが何かである」と仮定します:だから、いくつかの実装のアドバイスとして、私は次のように開始する

(アプリケーション自体は、スレッド内のユーザーのローカライズなど、サーバーのセッションウォッチドッグでした)自己と一緒に? "何らかのエラーが出ていますか? –

答えて

1

あなた自身が既に言及したように、あなたのdo_somethingにはすべてMainWindowクラスのインスタンスが作成されています。

第2に、do_something関数呼び出しは私にとって少し奇妙です。 私がこのニシキヘビの方法またはありませんが、私はそれを言及したようにあなたがそれを見ることができますほとんどすべてのチュートリアル、ハウツー年代とサンプルコードと思えばそれは議論の余地があります

def do_something(queue): 
    t = MainWindow() 
    t.changeLight(queue.get()) 

を好むだろう。

前回、私はこのようなことを実装しましたが、私は別のアプローチを採用しました。

私はGUIからスレッドを開始し、そのスレッドにキューを渡し、スレッドがトラフィックを処理させるようにしました。

GUIはアイテムのキューをチェックし、GUIを更新したキュー内の内容に基づいてサイクリック(100ミリ秒ごとに)を更新しました。

更新が完了するたびにスレッドが再開されます。

import Tkinter as tk 
import Queue 

class MainWindow(tk.Frame): 
    """ This is the GUI 
     It starts threads and updates the GUI 
     this is needed as tkinter GUI updates inside the Main Thread 
    """ 
    def __init__(self, *args, **kwargs): 
     # Here some initial action takes place 
     # ... 
     self.queue = Queue() 
     self.start_threads() 
     self.__running = True 
     self.update_gui() 

    def start_threads(self): 
     """ Here we start the threads 
      for ease of reading only one right now 
      thread_handler_class is a class performing 
      tasks and appending results to a queue 
     """ 
     thread = thread_handler_class(self.queue) 

    def update_gui(self): 
     """ Update the UI with Information from the queue """ 
     if not self.queue.empty(): 
      # we need to check for emptiness first 
      # otherwise we get exceptions if empty 
      while self.queue.qsize() > 0: 
       # handle the data 
       # self.queue.get() automatically reduces 
       # qsize return value next round so if no 
       # new elements are added to the queue, 
       # it will go to zero 
       data = self.queue.get() 
       # do stuff here 
       # ... 

     # Set up the cyclic task 
     if self.__running: 
      self.after(100, self.update_gui) 
      # if neccessary we can also restart the threads 
      # if they have a determined runtime 
      # self.after(100, self.start_threads)   

if __name__ == "__main__": 
    APP = MainWindow() 
    APP.mainloop() 
関連する問題