2016-09-28 2 views
0

Я пытаюсь создать игру с использованием Tkinter, которая может одновременно запускать функции из нескольких объектов класса с помощью потоков. В классе MainWindow у меня есть «игрок» и «игрок2», назначенный классу «Player».python: классы Threading из класса main_window

В классе «Player» есть функция «move», которая просто перемещает объект canvas.

При нажатии правой кнопки «игрок» начинает движение. Однако, как только нажата левая кнопка, кажется, что «игрок» остановлен для замены «player2».

Есть ли все-таки исправить это?

from tkinter import * 
from threading import Thread 
import time 


class MainWindow(Frame): 
    def __init__(self , parent): 
     self.backround = '#%02x%02x%02x' % (180, 180, 180) 
     self.main_width = 1905 
     self.main_height = 1002 

     Frame.__init__(self , parent , bg = self.backround) 
     self.pack(fill=BOTH, expand=1) 
     self.parent = parent 
     self.parent.geometry('1905x1002+0+0') 
     self.main_canvas = Canvas(self , width = self.main_width , height =  
     self.main_height , bg = 'white') 
     self.main_canvas.pack() 

     self.Keyboard_Events = Thread(target = self.keyboard_events) 
     self.Keyboard_Events.start() 

игроки

 self.player = Player(self.main_canvas , [125 , 125] , self) #(canvas , coords) 
     self.player2 = Player(self.main_canvas , [200 , 100] , self) #(canvas , coords) 

Callbacks

def keyboard_events(self): 
     def callback_mouse_primary(event): 
      self.player.move(0.01) 
     def callback_mouse_secondary(event): 
      self.player2.move(0.01) 

     root.bind('<Button-1>' , callback_mouse_primary) 
     root.bind('<Button-3>' , callback_mouse_secondary) 

игрок класса

class Player(Thread): 
    def __init__(self , canvas , coords , parent): 
     Thread.__init__(self) 
     self.setDaemon(True) 
     self.canvas = canvas 
     self.coords = coords 
     self.player_object = self.canvas.create_rectangle(self.coords[0]-25 , self.coords[1]-25 , self.coords[0]+25 , self.coords[1]+25) 

    def move(self , Time): 

     for y in range(100): 
      self.canvas.coords(self.player_object , self.coords[0]-25 , self.coords[1]-25 , self.coords[0]+25 , self.coords[1]+25) 
      self.coords[0] += 0.1 
      self.coords[1] += 0.1 
      self.canvas.update() 
      time.sleep(Time) 

    def Print_info (self): 
     print (self.coords) 

if __name__ == '__main__': 
    root = Tk() 
    main = MainWindow(root) 
    root.mainloop() 

Просто, чтобы сделать его ясно. Объекты игрока создаются в классе MainWindow, и функции внутри этих игроков выполняются в классе MainWindow. Есть ли все равно, чтобы потоки этих объектов игрока выполнялись независимо?

+1

вы должны ** никогда не ** обновлять gui в потоках, кроме основного потока ... вы можете выполнить всю логику и обработку, которые вы хотите в потоках ... но никогда не обновлять графический интерфейс в любом потоке, кроме main_thread –

ответ

0

1) Ваша потребность исправить вашу модель и есть разделение между моделью данных и/представления/визуализации:

players нужно только держать свои данные, и не отвечает за отрисовку ничего. У вас должен быть основной цикл рендеринга, который отвечает за чтение компонентов на дисплее, и поместите их соответственно.

2) players не threads, и их не нужно демонтировать. Threads работает как отдельный процесс. В вашем случае отдельный процесс заключается в том, чтобы начать перемещение игроков по определенной ставке:

def callback_mouse_primary(event): 
     t=Thread(target=self.player.move,kwargs={'Time': 0.01}) 
     t.start()