0

I'm working on an asynchronous TCP server.

All is going well, and I'm learning a lot from it, but I have a question related to the structure.

This is how the structure looks:

Global overview

The Server object is an asynchronous TCP server running in its own thread. It communicates with the GUI Controller object via thread-safe queue's.

On the main thread we've got the GUI Controller , the tkinter mainloop and the actual Tkinter GUI class.

here is some code to make it more clear:

clientlist = []
#queue's for communicating with server thread
buffer = queue.Queue()
buffer2 = queue.Queue()

root = Tk()
#GUI controller
controller = Controller(buffer,buffer2,clientlist,root)
#Make Tkinter GUI and give a reference to the controller
top = MainWindow(controller, root)
#Giving Tkinter GUI reference to the controller
controller.set_top(top)

t1 = threading.Thread(target=run_server, args=(buffer,buffer2))
t1.start()

controller.check_connections()


root.protocol("WM_DELETE_WINDOW", on_closing)
try:
    while controller.run:
        root.mainloop()
    print("[i] Joining server thread.")
    t1.join()

I have a hard time finding a nice way to make the Tkinter GUI communicate with the GUI controller. The idea I had here to give a reference to each others class is not working:

If I give the MainWindow a reference to Controller, I need to save it to a variable in the constructor of MainWindow. Then I need to update that variable each loop which is very demanding.

How can I give a reference the correct way, or is there a better way to let these two classes communicate?

Thanks a lot!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Jurze
  • 209
  • 2
  • 11
  • 2
    Set a placeholder for Window object in `Controller.__init__` and create a register function which can reassign it when called. – Dashadower Jan 19 '19 at 14:04
  • Thanks for your reply! The Window object needs to know the Controller object as well. So I could apply the same technique there. But then I would still need to call the register function each time the object or its properties change right? Or is there a way to give it an actual reference that points to the object? – Jurze Jan 19 '19 at 15:20
  • 1
    Relevant: [Mutli-threading with Tkinter](https://stackoverflow.com/a/14381671/7414759) – stovfl Jan 19 '19 at 18:47
  • @stovfl I already use the queue's for communicating between multiple threads.The question was about two objects in the same thread. I did manage to get it working though, I found that I forgot a few `self.` 's. So I was giving a reference the correct way. But I was sometimes writing to the object in the global scope, instead of the actual reference (both classes were in the same _.py_ file) Thanks for your help both! – Jurze Jan 20 '19 at 12:54

1 Answers1

0

I fixed this when moving both the Tkinter GUI class and the controller class to their own .py file instead of having both in the same file.

I found that I forgot some self.'s so the controller would try to acces the GUI object defined in the global scope instead of the reference I gave. After placing those self.'s all is working as I expected!

So for other people: If you want to give two objects a reference to each other:

  1. Set a placeholder for the other object in each constructor. (thanks @Dashadower)
  2. Give each class a method to reassign that placeholder with the actual reference (Give the object as an argument)

  3. Dont forget to call the objects reference of the other object. (USE self.)

Jurze
  • 209
  • 2
  • 11