Python:如何同时运行一个函数作为其他代码并实时更新其他代码



我最近开始使用pygame编码,为一个需要实时雷达的项目创建一个GUI雷达。我遇到的问题是我想在运行其余代码的同时运行 Ultra(( 函数,从而允许我实时更新"距离"变量。我希望这个距离变量更新屏幕上的标签。任何帮助将不胜感激。谢谢!

import pygame
import time
import sys
import RPi.GPIO as GPIO
import os
BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0)
GREEN = (0,155,0)
BLUE = (0,0,255)
pygame.init()
clock = pygame.time.Clock()
menuW = 400
menuH = 250

mainDisplay = pygame.display.set_mode((menuW, menuH))
pygame.display.set_caption("Radar ALPHA 1.0")
#FONTS
fontSmall = pygame.font.SysFont(None, 25)
fontBig = pygame.font.SysFont(None , 50)
#HOMEMADE FUNCTIONS

def ultra():
    global Distance
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)
    TRIG = 7
    ECHO = 11
    GPIO.setup(TRIG,GPIO.OUT)
    GPIO.output(TRIG,0)
    GPIO.setup(ECHO,GPIO.IN)
    time.sleep(1)
    print "Starting mesurement..."
    GPIO.output(TRIG,1)
    time.sleep(0.00001)
    GPIO.output(TRIG,0)
    while GPIO.input(ECHO) == 0:
        pass
    start = time.time()
    while GPIO.input(ECHO) == 1:
        pass
    stop = time.time()
    Distance = (stop-start) * 17000
    print Distance , " CM"

def message_small(msg,colour,width,height):
    screen_text = fontSmall.render(msg, True, colour)
    mainDisplay.blit(screen_text, [width, height])

def message_big(msg,colour,width,height):
    screen_text = fontBig.render(msg, True, colour)
    mainDisplay.blit(screen_text, [width, height])
def circle(display,r):
    pygame.draw.circle(display, WHITE, [500, 360], r, 3)
def button(bPosX,bPosY,bX,bY):
    pygame.draw.rect(mainDisplay, GREEN, [bPosX, bPosY, bX, bY] )

menuOn = True
guiOn = True
radarOn = True
dataOn = True
infoOn = True

 #VARs
radarSetup = True
ultraSetup = True
targetSpeed = 5
targetX = 200
targetY = 100
changeTX = 0
changeTY = 0

#MAIN BIT
while guiOn:
    while menuOn:
        #VARs and SETUP
        mainDisplay.fill(WHITE)
        message_big("Radar Menu ALPHA 1.0", RED, 5,5)
        message_small("Press R to go to Radar", BLACK, 5,50)
        message_small("Press D to go to Data", BLACK , 5, 70)
        message_small("Press I to go to Info" , BLACK, 5, 90)
        message_small("Press Q to Quit" , BLACK, 250,220)

        pygame.display.update()

        #EVENT HANDLER
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                menuOn = False
                radarOn = False
                dataOn = False
                infoOn = False
                guiOn = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r:
                    menuOn = False
                    dataOn = False
                    infoOn = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_d:
                    menuOn = False
                    radarOn = False
                    infoOn = False

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_i:
                    menuOn = False
                    radarOn = False
                    dataOn = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    radarOn = False
                    dataOn = False
                    infoOn = False
                    guiOn = False
                    menuOn = False
        #LOGICS

    while radarOn:
        while radarSetup:
            pygame.init()
            clock = pygame.time.Clock()
            menuW = 1000
            menuH = 720
            radarDisplay = pygame.display.set_mode((menuW, menuH))
            pygame.display.set_caption("Radar ALPHA 1.0")
            radarSetup = False
        #CLEAR and setup
        radarDisplay.fill(WHITE)
        message_big("RADAR v1.0",RED, 400 , 20)


        #EVENT HANDLER
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                menuOn = False
                radarOn = False
                dataOn = False
                infoOn = False
                guiOn = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    changeTX =  - targetSpeed
                if event.key == pygame.K_RIGHT:
                    changeTX = targetSpeed
                if event.key == pygame.K_UP:
                    changeTY =  - targetSpeed

                if event.key == pygame.K_DOWN:
                    changeTY = targetSpeed

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    changeTX = 0
                if event.key == pygame.K_RIGHT:
                    changeTX = 0
                if event.key == pygame.K_UP:
                    changeTY = 0

                if event.key == pygame.K_DOWN:
                    changeTY = 0


        #Circle Set UP
        pygame.draw.circle(radarDisplay, BLACK, [menuW/2, menuH/2], 300)            
        pygame.draw.circle(radarDisplay, GREEN, [menuW/2, menuH/2], 20)
        circle(radarDisplay,50)
        circle(radarDisplay,100)
        circle(radarDisplay,150)
        circle(radarDisplay,200)
        circle(radarDisplay,250)    
        #LOGICS
        targetX += changeTX
        targetY += changeTY

        pygame.draw.circle(radarDisplay, RED, [targetX, targetY], 5)
        pygame.display.update()
        clock.tick(2)
    while dataOn:
        #CLEAR
        mainDisplay.fill(WHITE)
        message_small("DATA",RED, 150 , 100)
        pygame.display.update()
        #VARs
        #EVENT HANDLER
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                menuOn = False
                radarOn = False
                dataOn = False
                infoOn = False
                guiOn = False
        #LOGICS

    while infoOn:
        #CLEAR
        mainDisplay.fill(WHITE)
        message_small("INFO",RED, 150 , 100)
        pygame.display.update()
        #VARs
        #EVENT HANDLER
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                menuOn = False
                radarOn = False
                dataOn = False
                infoOn = False
                guiOn = False
        #LOGICS


    clock.tick(10)
pygame.quit()
quit()
线程

与代码分开运行。如果要在线程之间共享数据,请确保它们是包含数据的线程安全对象,否则在写入错误或数据更改后出现其他错误后会被读取。https://docs.python.org/3.4/library/threading.html

另一种方法是使用用于某些主要处理的多处理库。

import threading
import queue
import time
def mymethod(storage, stop):
    """Continuously add counters to the given storage queue.
    Args:
        storage (queue.Queue): Hold the data.
        stop (threading.Event): Thread safe signal for when to quit.
    """
    counter = 0
    while not stop.is_set():
        storage.put(counter)
        counter += 1
        time.sleep(0.1)
# end mymethod
if __name__ == "__main__":
    storage = queue.Queue()
    stop = threading.Event()
    th = threading.Thread(target=mymethod, args=(storage, stop))
    # th.daemon = True # Daemon threads are cleaned up automatically
    th.start() # Run
    for i in range(10):
        # We don't actually know how fast each program runs. Order will not be saved.
        print(storage.get(0)) # Pull the thread counter number. 0 means no wait
        storage.put(i) # Set my counter number
        time.sleep(0.2) # Just to show things aren't happening in any order.
    time.sleep(1) # Do other stuff and forget about it.
    stop.set() # Clear the stop signal, so the thread can leave the loop and quit
    th.join(0) # Safely close the thread when it is done
    print("thread closed")
    while not storage.empty():
        print(storage.get(0))

相关内容

最新更新