python: NameError в subthread при доступе к mainthread - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь написать карточную игру, в которой используются как сокеты, так и tkinter. Я довольно далеко продвинулся в этом, но теперь, похоже, застрял в объединении двух модулей. Я попытался упростить мой код, потому что он стал довольно длинным. Я получаю NameError в клиентском скрипте:

### Client Script

from threading import Thread
import socket
import tkinter as tk
from tkinter import *

ClientSocket = socket.socket()
host = '127.0.0.1'
port = 1234
ClientSocket.connect((host, port))

class guithread(Thread):
    def __init__(self, arg):
        self.arg = arg
        self.root = tk.Tk()
        self.run()

    def run(self):
        g = Thread(target = fgame, args = (ClientSocket, playernr, )) 
        #I had to write the game process as a function because 
        #when using a class the GUI doesn't open for some reason

        g.SetDaemon(True) #tried this without success
        g.start()
        self.root.title(self.nr)
        self.root.geometry('1000x600')
        self.root.mainloop()

class game(Thread):    #not used in this example
    def __init__(self, ClientSocket, playernr):
        #super(game, self).__init__()
        self.ClientSocket = ClientSocket
        self.playernr = playernr
        self.run()

    def run(self):
        while True:
            Response = (ClientSocket.recv(1024)).decode('utf-8')
            if not Response:
                pass
            else:
                print(Response)
                decrypt(Response)

def fgame(ClientSocket, playernr):
    global gui #doesn't seem to have an impact
    print(gui.arg)   #this causes the NameError
    while True:
        Response = (ClientSocket.recv(1024)).decode('utf-8')
        if not Response:
            pass
        else:
            print(Response)
            decrypt(Response)

def decrypt(message):
    #...do some stuff with the message
    print(gui.arg)    #this causes the NameError

txt = 'HelloWorld'
gui = guithread(txt)

Я получаю следующую ошибку: NameError: gui ist not defined как в функции fgame, так и в расшифровке - так что, очевидно, подпоток не может получить доступ к основному потоку.

Поэтому, столкнувшись с NameError, я попытался решить ее с помощью super () и setDaemon, но оба не работали (хотя я должен сказать, что это несколько выходит за рамки моих навыков), super (), вероятно, из-за неудачи реализовать игровую функцию как класс. Как указывалось выше, GUI не открывался при использовании класса, я полагаю, потому что основной поток ожидал, пока функция сокета не закончит sh, чего не произойдет, потому что это oop. Причина, по которой я открываю подпоток для сокетов, заключается в том, что когда я пытался открыть второй поток ниже последней строки, поток не запускался - опять же, вероятно, потому, что он ожидал, пока поток tkinter завершит работу sh.

К сожалению, код не может быть развернут, он просто много работает с сервером и клиентом и объединяет несколько модулей. Может быть, кто-то сталкивался с той же проблемой в прошлом или имеет представление о том, почему функции вспомогательных потоков не могут получить доступ к основным потокам.

...