簡體   English   中英

在Python Zelle圖形中實現多線程

[英]Implement multithreading in Python Zelle graphics

我正在創建一個使用Zelle的graphics.py在窗口中打開世界地圖的程序。 它具有一個在地圖上繪制點的功能,另一個功能是在屏幕上顯示這些點1秒鍾后將其取消繪制(繪制后存儲在列表中)。 我希望這些函數可以同時工作,但是當在線程中調用addDots()函數時,它不會在窗口中繪制點,而只是停頓。 這是我運行的模塊:

import thread
import threading
import time
import random
import sys
sys.path.append('..')
from Display import map
import tester
import datetime


dots = list(())

def deleteDots():
    while 1==1:
        tF = datetime.datetime.now()
        a = 0
        for i in range(len(dots)):
            tD = tF - dots[i-a][2]
            tD = int(str(tD)[5:7])
            if tD >= 1:
                map.deletePoint(dots[i-a][0],dots[i-a][1])
                dots.pop(i-a)
                a = a+1
def addDots():
    oldResponseCount = tester.getResponseCount()
    oldResponseCount = int(str(oldResponseCount))
    while 1==1:
        print(oldResponseCount)
        newResponseCount = tester.getResponseCount()
        newResponseCount = int(str(newResponseCount))
        print(newResponseCount)

       if(newResponseCount != oldResponseCount):
            difference = newResponseCount - oldResponseCount

            for i in range(difference):
                lat = random.randint(-90,90)
                long = random.randint(-180,180)
                map.drawPoint(lat,long)
                tI = datetime.datetime.now()
                dots.append([lat,long,tI])

       oldResponseCount = newResponseCount

if __name__ == '__main__':
    threading.Thread(target=addDots).start()
    threading.Thread(target=deleteDots).start()

這里是地圖模塊,它在圖形窗口上繪制地圖,並包含繪制和刪除點的功能:

from graphics import *
import math
import images
size = 0.6
Circles = list(())
win = GraphWin("My Window", 1920*size, 1080*size)
win.setBackground('blue')
images.test(size)
myImage = Image(Point(960*size,540*size), "../Display/temp.gif")

myImage.draw(win)
import time

def drawPoint(lat,long):
    x = int(long*5.3+960)*size
    y = int(lat*(-5.92)+540)*size
    pt = Point(x,y)
    cir = Circle(pt,5)
    cir.setFill(color_rgb(255,0,0))
    Circles.append([cir,x,y])
    cir.draw(win)

def deletePoint(lat,long): 
    x = int(long*5.3+960)*size
    y = int(lat*(-5.92)+540)*size
    for c in Circles:
        if c[1]==x and c[2]==y:
            c[0].undraw()

我應該怎么做呢?

有幾個問題必須解決。 首先,任何調用tkinter的graphics.py命令(即導致繪制/未繪制內容的命令)必須由主(主)線程發出。 因此,我們需要輔助線程將繪圖請求傳達給主線程。

其次,您有兩個輔助線程都在修改“ Circles和“ dots列表-您需要同步(鎖定)訪問這些列表,以便一次只能有一個線程可以修改或迭代它們。

下面以我對您的代碼的修改為例。 我消除了map和tester例程,因為我只是將一個點放在一個線程的窗口上,並在另一個線程中將它們刪除一秒后將其刪除:

from threading import Thread, Lock
from queue import Queue  # use for thread-safe communications
from random import randint
import time

from graphics import *

def drawPoint(lat, long):
    x = int(long * 5.3 + 960)
    y = int(lat * -5.92 + 540)

    point = Point(x, y)
    circle = Circle(point, 5)
    circle.setFill(color_rgb(255, 0, 0))

    circles_lock.acquire()
    circles.append(circle)
    circles_lock.release()

    actions.put((circle.draw, win))

def deletePoint(lat, long):
    global circles

    x = int(long * 5.3 + 960)
    y = int(lat * -5.92 + 540)

    keep_circles = []

    circles_lock.acquire()
    for circle in circles:
        center = circle.getCenter()

        if center.getX() == x and center.getY() == y:
            actions.put((circle.undraw,))
        else:
            keep_circles.append(circle)

    circles = keep_circles
    circles_lock.release()


def deleteDots():
    global dots

    while True:
        keep_dots = []

        dots_lock.acquire()
        now = time.time()

        for dot in dots:
            lat, long, then = dot

            if now - then >= 1.0:
                deletePoint(lat, long)
            else:
                keep_dots.append(dot)

        dots = keep_dots
        dots_lock.release()

        time.sleep(0.5)

def addDots():
    while True:
        lat = randint(-90, 90)
        long = randint(-180, 180)

        drawPoint(lat, long)

        dots_lock.acquire()
        dots.append((lat, long, time.time()))
        dots_lock.release()

        time.sleep(0.25)

win = GraphWin("My Window", 1920, 1080)

circles = []
circles_lock = Lock()

dots = []
dots_lock = Lock()

actions = Queue()

Thread(target=addDots, daemon=True).start()
Thread(target=deleteDots, daemon=True).start()

while True:
    if not actions.empty():
        action, *arguments = actions.get()
        action(*arguments)

    time.sleep(0.125)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM