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

时间:2014-12-19 21:11:44

标签: python pygame

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

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()

1 个答案:

答案 0 :(得分:0)

线程与代码分开运行。如果要在线程之间共享数据,请确保它们是包含数据的线程安全对象,否则在写入错误或数据发生更改时的其他错误后会读取。 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))