1

I'm sure it's a simple fix but I'm just spacing out here on my basics. I need to incorporate a Gui that simply pops up and states that a connection has been made between the client and the server.

I can get the GUI to pop up when it is on top of my code with all of my variables but It won't run underneath my code which is where the connection that I need it to display is defined.

# it will run but (address) is not defined yet
import socket
from tkinter import *

root = Tk()
theLabel = Label(root,text="Connection from {address} has been established.")
theLabel.pack()
root.mainloop()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1234))
s.listen(5)

while True:
  clientsocket, address = s.accept()
  print(f"Connection from {address} has been established.")
  clientsocket.send(bytes("HELL YEAH FAM!!! WE DID IT!!","utf-8"))
  clientsocket.close()

it has no error message, it just won't run the GUI.

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
Angie
  • 21
  • 2
  • 1
    `root.mainloop()` won't exit until the window is closed. You need to move that to the very end of the program - and you need to move the creation of the label to a later point as well, so you can fill in the actual address. – jasonharper Jul 23 '19 at 20:23
  • The GUI is essentially run entirely within that one `mainloop()` call. Whatever you put after runs only after the GUI exits. You probably wanted to run an asynchronous connection attempt, but I'm not sure how to fit that with Tk's event loop. https://stackoverflow.com/questions/16745507/tkinter-how-to-use-threads-to-preventing-main-event-loop-from-freezing might help (with an example of `after` to schedule a poll). Virtual events are probably a cleaner way, but I don't know if it's thread safe to inject them. – Yann Vernier Jul 23 '19 at 20:33

2 Answers2

2

You have to configure everything, then you can call a function for a connection and then at the end call root.mainloop(). Here are some of the work you need to make:

from socket import AF_INET, SOCK_STREAM, socket, gethostname
from tkinter import *
from tkinter import ttk

IP = gethostname() # or "127.0.0.1"
PORT = 1337

root = Tk()
root.title("")
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

for child in mainframe.winfo_children(): 
child.grid_configure(padx=5, pady=5)

root.bind('<Return>', connectionFunc)

def connectionFunc(*args):
    # this way you dont have to close the socket.
    with socket(AF_INET, SOCK_STREAM) as s:
        s.listen()
        s.bind((IP, PORT))
        conn, addr = s.accept()
        with conn:
            print(f"connection from: {addr}")
            while True:
                data = conn.recv(1024)
                if not data:
                    break
                conn.sendall(data)

root.mainloop()
1

You should use thread for waiting connection:

import socket
import threading
from tkinter import *

def wait_connection():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((socket.gethostname(), 1234))
    s.listen(5)

    while True:
        clientsocket, address = s.accept()
        msg.set(f"Connection from {address} has been established.")
        clientsocket.send(bytes("HELL YEAH FAM!!! WE DID IT!!","utf-8"))
        clientsocket.close()

root = Tk()
msg = StringVar(value='Waiting for connection ...')
theLabel = Label(root,textvariable=msg)
theLabel.pack()

# start a thread for waiting client connection
threading.Thread(target=wait_connection, daemon=True).start()

root.mainloop()
acw1668
  • 40,144
  • 5
  • 22
  • 34