【问题标题】:Tk python app keeps freezing when using QueueTk python 应用程序在使用队列时一直冻结
【发布时间】:2016-05-06 13:37:21
【问题描述】:

每次我运行我的 TK 应用程序时它都会死机,请相信这与 Queue 模块有关。

我的代码:

 import socket, os, multiprocessing, queue
import tkinter as tk

#---global variables---#

setup = ''
cleintsocket = ''
port = 0
q = queue.Queue()

#---Defs---#

def setup():
    global host, port, user
    host = setup_host_box.get()
    port = setup_port_box.get()
    user = setup_user_box.get()
    if port == '':
        port = 8545
    create_sock(host, int(port))

def connect_buffer(self, hostname, connectingport):
    connect(self, hostname, connectingport)

def connect(self, hostname, connectingport):
    '''connects to a port'''
    if hostname == '':
        hostname = 'localhost'
    self.connect((hostname, connectingport))
    resvbackgroung = multiprocessing.Process(target = resv)
    resvbackgroung.start()
    chat()

def create_sock(nhost, nport):
    '''create the cleint's socket'''
    global cleintsocket
    cleintsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connect(cleintsocket, nhost, nport)

def send(username, cleintsock):
    '''to send a message'''
    usrmsg = (username + ' - ' + chat_msg_box.get()).encode()
    cleintsock.send(usrmsg)

def resv():
    '''resive subscript, run through mutiprosses module'''
    while True:
        rmsg = cleintsocket.recv(1024).decode()
        q.put(rmsg)

def chat():
    '''loads chat page'''
    setup_host_text.pack_forget()
    setup_host_box.pack_forget()
    setup_port_text.pack_forget()
    setup_port_box.pack_forget()
    setup_user_text.pack_forget()
    setup_user_box.pack_forget()
    setup_confirm_button.pack_forget()
    chat_msg_display_text.pack()
    chat_msg_box.pack()
    chat_msg_send_button.pack()
    chat_disconnect_button.pack()
    while True:
        while not q.empty():
            msg = q.get()
            chat_msg_display_text.insert('END.END', msg)

def start():
    '''starts the setup page'''
    setup_host_text.pack()
    setup_host_box.pack()
    setup_port_text.pack()
    setup_port_box.pack()
    setup_user_text.pack()
    setup_user_box.pack()
    setup_confirm_button.pack()


def disconnect():
    '''safely closes the socket and sends a desconnect msg'''
    cleintsocket.send((user + 'has disconnected').encode())
    cleintsocket.close()
    quit()

def send_button_callback():
    '''add a buffer to allow time for 'cleintsocket' to be defined in 'create_sock()'''
    send(user, cleintsocket)

#---TK Setup---#

#--window setup--#

window = tk.Tk()
window.title('Chat')
window.geometry('600x600')
window.configure(background='#ffffff')

#--connection setup page--#

setup_host_text = tk.Label(window, text = 'Host')
setup_host_box = tk.Entry(window, bg = '#ffffff')
setup_port_text = tk.Label(window, text = 'Port')
setup_port_box = tk.Entry(window, bg = '#ffffff')
setup_user_text = tk.Label(window, text = 'Username')
setup_user_box = tk.Entry(window, bg = '#ffffff')
setup_confirm_button = tk.Button(window,text = 'Connect', command = setup)

#--chat page--#

chat_msg_box = tk.Entry(window, bg='#ffffff')
chat_msg_send_button = tk.Button(window, text = 'send', command = send_button_callback)
chat_msg_display_text = tk.Text(window, width=600, height=20, insertborderwidth = 3, wrap = 'word')
chat_disconnect_button = tk.Button(window, text = 'Disconnect', command = disconnect)

#--------------#

start()

谢谢,

CB

【问题讨论】:

  • 请不要链接到其他网站上的代码。如果您还没有阅读过stackoverflow.com/help/mcve,您可能想阅读。
  • @BryanOakley 实际上我已经阅读了关于“如何创建最小、完整和可验证的示例”的页面,它没有说你不应该把代码放在另一个网站上,我把我的代码放在粘贴箱上,因为它更容易将代码格式化(顺便说一句,谢谢 Pythonista 的编辑)成一种易于人们阅读的代码格式(而不是制表符)每一行代码),所以在你告诉别人阅读 MCVE 页面之前,你为什么不呢?
  • MCVE 不仅仅是放置代码的位置。你已经包含了很多不必要的代码。此外,您不必“标记每一行”。复制格式正确的代码。粘贴到编辑框中。选择所有代码。单击类似于{} 的按钮。你已经完成了。
  • @BryanOakley 在你的第一条评论中,你抱怨我把我的代码放在 pastebin 上(在 MCVE 中没有提到你不应该这样做)而不是不必要的代码,我的很多代码应用程序依赖于其他功能,例如connect() 函数无法运行(没有它,代码将无法运行,直到 create_sockcreate_sock 无法运行,直到 setup() 运行,我也在使用我从未使用过的模块组合之前一起用过,不知道是不是发生了什么冲突导致卡死。最后感谢编辑框里的提示,以后会继续使用。

标签: python-3.x tkinter queue


【解决方案1】:

问题出在您的connect 函数中:

您设置了多处理,将函数 resv 作为您刚刚生成的此进程的目标。

然后您开始该过程,并在此之后直接调用chat,其中包含while True 循环。

这会阻塞 tkinter 的主事件线程。

【讨论】:

  • 啊,所以我需要某种形式的缓冲区还是需要将 while 循环粘贴到另一个函数中?
  • 经过一番谷歌搜索后,我发现了一个对我有很大帮助的线程 ([link]stackoverflow.com/questions/18679102/…),结果证明我可以使用self.after(1000, funtion1),因此 update_text 会安排在一组后调用它自己时间。
猜你喜欢
  • 1970-01-01
  • 2015-01-29
  • 2011-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多