0

I have created tkinter GUI, where a sever socket program which accept connections from client and create a simple window for each clients. I tried to add image icons into it , but the image icons are not displayed and (I can add image to simple tkinter window seperately, while combine that to the below GUI fails.)

If i add images into the window then the window is not opened, (it opened ,while commenting the image add lines from the program)

S.py

import socket
from tkinter import *
from threading import Thread
from PIL import ImageTk, Image


root = Tk()
root.title("GUI")
root.geometry('350x200')
root.resizable(width=FALSE, height=FALSE)




def con():
    act_lb1.destroy()
    label_2 = Label(root, text="Activated")
    label_2.place(x=100, y=20, height=55)


    try:



        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        ip = "0.0.0.0"
        port = 4141
        s.bind((ip, port))
        s.listen(5)



        def window(c, ):
            while True:


                popup1 = Toplevel(root)
                popup1.title('Notification')
                popup1.geometry('250x100')
                prompt = " connectiing"
                label1 = Label(popup1, text=prompt, width=len(prompt))
                label1.pack(fill="none", expand=True)

                def close_after_2s():
                    popup1.destroy()

                popup1.after(4000, close_after_2s)
                #popup1.mainloop()


                top = Toplevel(root)
                top.title('H-PINGER')
                top.geometry("200x200")
                top.resizable(width=FALSE, height=FALSE)

                img = ImageTk.PhotoImage(Image.open("13.png"))
                panel = Label(top, image=img)

                prompt = "connected"
                user_lb = Label(top, text=prompt, width=len(prompt))





                user_lb.place(x=50, y=1, height=39)
                panel.place(x=6, y=1, height=39, width=39)

                def rm():
                      pass

                while True:

                   Thread(target=rm).start()

        while True:

            c, addr = s.accept()
            print('Connected with ' + addr[0] + ':' + str(addr[1]))
            if addr[0] != '':
                root.withdraw()



                thread2 = Thread(target=window, args=(c,))
                thread2.start()

        c.close()
        s.close()


    except socket.error as msg:
        print('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
        sys.exit()





sp = Button(root, text='Activate', anchor="center", font=30, width="18", height=3,bd=0, activebackground="darkgrey",  command=(lambda: con()))
act_img = PhotoImage(file="l3.png") # make sure to add "/" not "\"
sp.config(image=act_img)
sp.place(x=130,y=80, height=55, width=64)
act_lb1 = Label(root, text="Press the button to activate")
act_lb1.place(x=100, y=20, height=55)

root.mainloop()

C.py

import socket


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 4141

ip = input('Enter the IP Address::')

s.connect((ip, port))

13.png

Kpras
  • 63
  • 1
  • 13
  • You shouldn't use more than one instance of `Tk`. All windows that you create after you first root window should be instances of `Toplevel`. Read [this answer](https://stackoverflow.com/a/48045508/3714930) for an explanation. Also, tkinter doesn't play well with `while True` loops, since its `mainloop` basically already is an infinite loop. – fhdrsdg Jan 31 '19 at 10:01
  • Then how can i replace the while loop in my program – Kpras Jan 31 '19 at 10:02
  • Why do you think you need a `while True` loop in the first place? – fhdrsdg Jan 31 '19 at 10:07
  • one while loop for accepting new connections and call the new window creating function and other while loop is for receiving messages from client and sending messages to the client(here i didn't ad those two functions to avoid a lenghthy question) – Kpras Jan 31 '19 at 10:15
  • I have added the Toplevel into every sub windows and keep the TK instance only for main loop. still the windows are not displaying – Kpras Jan 31 '19 at 10:21
  • Try putting the while loop for listening connection into another thread. – acw1668 Jan 31 '19 at 10:56
  • sorry , i didn't get it..please explain it.? – Kpras Jan 31 '19 at 11:04
  • It means move the while loop containing `s.accept()` to a thread. – acw1668 Jan 31 '19 at 12:29
  • i have remove the content and add the content in the while loop into a fucntion .(def accept()) then i used a new thread in the removed while loop position to call the function. **new_thread= Thread(target=accept()).start()**.. Bit its not working still – Kpras Jan 31 '19 at 12:54

1 Answers1

0

Never use while loop in main thread as it will block the tkinter event processing loop (mainloop()). So better move the while loop in another thread. Below is an example code:

import socket
from tkinter import *
from threading import Thread

root = Tk()
root.title("GUI")
root.geometry("350x200")
root.resizable(width=False, height=False)

def handle_client(c, addr):
    win = Toplevel()
    win.img = PhotoImage(file='l3.png')
    Label(win, image=win.img).pack()
    Label(win, text='Client: {}'.format(addr)).pack()
    msg = Label(win)
    msg.pack()
    while True:
        data = c.recv(1024)
        if data:
            msg.config(text=data)
        else:
            break

def accept_connection():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    ip = '0.0.0.0'
    port = 4141
    s.bind((ip, port))
    s.listen(5)
    while True:
        print('Waiting connection ...')
        c, addr = s.accept()
        print('Connected:', addr)
        t = Thread(target=handle_client, args=(c, addr))
        t.setDaemon(True)
        t.start()

def con():
    act_lb1.config(text='Activated')
    sp.destroy()
    t = Thread(target=accept_connection)
    t.setDaemon(True)
    t.start()

sp = Button(text='Activate', anchor='center', font=30, width=18, height=3, bd=0, activebackground='darkgrey', command=con)
act_img = PhotoImage(file='l3.png')
sp.config(image=act_img)
sp.place(x=130, y=80, height=55, width=64)

act_lb1 = Label(text='Press the button to activate')
act_lb1.place(x=100, y=20, height=55)

root.mainloop()

Sample client code to connect the above server:

import socket
import sys

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 4141))
s.send(b'hello' if len(sys.argv) == 1 else str.encode(sys.argv[1]))
s.close()
acw1668
  • 40,144
  • 5
  • 22
  • 34