简体   繁体   中英

How can I run a discord client and pygame at the same time with Threading?

I am trying to make my code take messages from discord using discord api and putting it on a black screen with said message in the center using pygame. The get_message() and main_window() functions both work separately but when I put it together with Threading, get_message() doesn't seem to work.

My code

import discord
import pygame
from threading import Thread

client = discord.Client()
new_message = "Potato"

pygame.font.init()
font = pygame.font.Font(None, 45)
color = (255, 255, 255)
txt = font.render(new_message, True, color)

def main():
    t1 = Thread(target=main_window())
    t3 = Thread(target=get_message())
    t3.start()
    t1.start()

def main_window():
    global new_message
    info = pygame.display.Info()
    screen = pygame.display.set_mode((info.current_w, info.current_h), pygame.FULLSCREEN)
    screen_rect = screen.get_rect()
    clock = pygame.time.Clock()
    done = False

    while not done:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    done = True

screen.fill((30, 30, 30))
screen.blit(txt, txt.get_rect(center=screen_rect.center))

pygame.display.flip()
clock.tick(30)

def get_message():

    @client.event
    async def on_ready():
        print('We have logged in as {0.user}'.format(client))

    @client.event
    async def on_message(message):
       if message.author == client.user or message.author.id == MY_USER_ID:
           return
       if message.channel.id == MY_CHANNEL_ID:
           if message.content != " ":
               global new_message
               global txt
               new_message = message.content
               txt = font.render(new_message, True, color)

    client.run("MY_ACCESS_KEY")

if name == 'main':
    pygame.init()
    main()

I am pretty new to Python so if you have any cleanup or suggestions to make I would greatly appreciate it! Thanks!

It's possible that rendering the text in a separate thread is causing the problem. According to the pygame font render() documentation, the method is not thread safe.

I modified your code by moving the font.render() calls and everything to do with pygame into the main_window() function. In each pass of the pygame event loop it checks if the global new_message has changed and renders the text if it has.

EDIT: I just noticed that when you created the threads you specified the functions incorrectly. It should be Thread(target=myFunc) (reference to the function) instead of Thread(target=myFunc()) (call the function and pass the result).

import discord
import pygame
from threading import Thread

client = discord.Client()
new_message = "Potato"

color = (255, 255, 255)

def main():
    t1 = Thread(target=main_window) # no parentheses on function
    t3 = Thread(target=get_message)
    t1.start()
    t3.start()

def main_window():
    pygame.init()
    pygame.font.init()

    font = pygame.font.Font(None, 45)
    info = pygame.display.Info()
    screen = pygame.display.set_mode((info.current_w, info.current_h), pygame.FULLSCREEN)
    screen_rect = screen.get_rect()
    clock = pygame.time.Clock()

    last_message = new_message # inital message
    txt = font.render(new_message, True, color) # renter initial text

    done = False
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    done = True

        if new_message != last_message: # message was changed by other thread
            last_message = new_message
            txt = font.render(new_message, True, color) # re-render text

        screen.fill((30, 30, 30))
        screen.blit(txt, txt.get_rect(center=screen_rect.center))

        pygame.display.flip()
        clock.tick(30)

def get_message():

    @client.event
    async def on_ready():
        print('We have logged in as {0.user}'.format(client))

    @client.event
    async def on_message(message):
        if message.author == client.user or message.author.id == MY_USER_ID:
            return
        if message.channel.id == MY_CHANNEL_ID:
            if message.content != " ":
                global new_message
                new_message = message.content

        client.run("MY_ACCESS_KEY")

if name == 'main':
    main()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM