-1

Every time I Run my TK app it freezes, believe that it is some thing to do with the Queue module.

My code:

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

Thank you,

CB

Pythonista
  • 11,377
  • 2
  • 31
  • 50
C.B
  • 32
  • 1
  • 9
  • 1
    Please don't link to code on another site. You might want to read http://www.stackoverflow.com/help/mcve if you haven't already. – Bryan Oakley May 06 '16 at 13:47
  • @BryanOakley Actually I _have_ read the page on 'How to create a Minimal, Complete, and Verifiable example' and it _doesn't_ say that you should not put code on another website, I put my code on paste bin because it is easier to format code (By the way, thank you Pythonista for the edit) into a easy format for people to read as code (rather than tabing every line of code), so before you tell someone to read the MCVE page, why don't you? – C.B May 07 '16 at 09:25
  • MCVE is more than just where to put the code. You've included a lot of unnecessary code. Also, you don't have to "tab every line". Copy your well-formatted code. Paste into the edit box. Select all the code. Click the button that looks like `{}`. You're done. – Bryan Oakley May 07 '16 at 09:32
  • @BryanOakley In your first comment you complained about me putting my code on pastebin(which is not mentioned in MCVE as something you shouldn't do) and not unnecessary code, a lot of the code in my app is dependant on other functions e.g. the `connect()` function can't run(with out it the code would not run until the `create_sock`, `create_sock` can't run until `setup()` is run, also I'm using a combination of modules I have never used together before so I don't know if/what conflicts have happen causing it to freeze. Finally Thank you for the tip in the edit box, I shall use it from now on. – C.B May 07 '16 at 10:44

1 Answers1

0

The problem is in your connect function:

You setup multiprocessing, put the function resv as the target for this process you have just spawned.

You then start the process, and you call chat directly after this which has a while True loop in it.

This blocks tkinter's main event thread.

Pythonista
  • 11,377
  • 2
  • 31
  • 50
  • Ah, so I need some form of buffer or do I need to stick the while loop in another function? – C.B May 07 '16 at 08:58
  • After a bit of googling I came across a thread ([link]http://stackoverflow.com/questions/18679102/tkinter-managing-my-event-loops-alongside-my-mainloop[link]) that helped greatly turns out I could use a `self.after(1000, funtion1)` so the update_text would arrange to call its self after a set amount of time. – C.B May 07 '16 at 09:29