0

I am new to python and especially tkinter, and I have gone through all of the examples on here but I'm still stuck.

I am trying to create something that sends messages back and forth, and currently having trouble updating the reply. I have taken bits out and just tried to manually update the label but no such luck, it may be something to do with it being on a tab? or even because I'm using grid to place my frames. Anyhow, any help would be deeply aprreciated.

'''

class SharedInformation():
    '''
        Class: Information thats passed between networking and gui classes
    '''
    def __init__(self):
        self.manual_command_response = tk.StringVar()


class Thread(threading.Thread):
    '''
        Class:Responsible for getting messages to and from the smart via Etherent
    '''
    def __init__(self, thread_name, thread_ID,info):
        threading.Thread.__init__(self)
        self.thread_name = thread_name
        self.thread_ID = thread_ID
        self.shared_info = info

        # helper function to execute the threads
    def run(self) -> None:
        eth_data = ""
        while True:
            print("GOT DATA")
            print(type(eth_data))

            protobuf = receive_data(eth_data)
            print(protobuf)
            temp = decode_manual_message(protobuf)

            self.shared_info.manual_command_response.set(temp)
            print("Updated to :" + self.shared_info.manual_command_response.get())


class DTerm(tk.Tk):
    '''
    Class: Main GUI class
    '''
    def __init__(self):
        super().__init__()
        # Initalise Networking
        initalise_network()

        self.info = SharedInformation()

        # Receiving network thread
        self.thread1 = Thread("EthRec", 1000, self.info)
        self.thread1.start()

        self.root = tk.Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.root.iconify)
        # make Esc exit the program
        self.root.bind('<Escape>', lambda e: self.root.destroy())
        self.root.title("d-term")
        self.root.attributes('-fullscreen', False)

        #Style the root page
        self.style = ttk.Style()
        self.style.theme_create( "MyStyle", parent="alt", settings={
            "TNotebook": {"configure": {"tabmargins": [2, 5, 2, 0] } },
            "TNotebook.Tab": {"configure": {"padding": [50, 50] },}})

        self.style.theme_use("MyStyle")

        # Create the tabs
        self.tabControl = ttk.Notebook(self.root)
        self.root.grid_columnconfigure(0, weight=1)
        self.root.grid_columnconfigure(1, weight=1)
        self.root.grid_columnconfigure(2, weight=1)
        self.root.grid_columnconfigure(3, weight=1)
        self.root.grid_columnconfigure(4, weight=1)
        self.root.grid_columnconfigure(5, weight=1)

        self.root.grid_rowconfigure(0, weight=1)
        self.root.grid_rowconfigure(1, weight=1)
        self.root.grid_rowconfigure(2, weight=1)
        self.root.grid_rowconfigure(3, weight=1)
        self.root.grid_rowconfigure(4, weight=1)
        self.root.grid_rowconfigure(5, weight=1)

        self.stringy = tk.StringVar()
        self.stringy.set('Hello')

        t = Label(self.root, textvariable=self.stringy, height=10,width=20)
        t.grid(row=0, column=0, sticky="w")
        self.width= self.root.winfo_screenwidth()
        self.height= self.root.winfo_screenheight()

        self.tabControl.grid(row=1,column=0, padx=0, pady=50)
        self.tabControl.grid_columnconfigure(1, weight=1)
        self.tabControl.grid_rowconfigure(1, weight=1)

        self.tab1 = ttk.Frame(self.tabControl, width=self.width, height=600)
        self.tab2 = ttk.Frame(self.tabControl, width=self.width, height=600)
        self.tab3 = ttk.Frame(self.tabControl, width=self.width, height=600)
        self.tab4 = ttk.Frame(self.tabControl, width=self.width, height=600)
        self.tab5 = ttk.Frame(self.tabControl, width=self.width, height=600)
        self.tab6 = ttk.Frame(self.tabControl, width=self.width, height=600)

        self.tabControl.add(self.tab1, text ='Manual Commands')
        self.tabControl.add(self.tab2, text ='Sensor Commands')
        self.tabControl.add(self.tab3, text ='ADCP Commands')
        self.tabControl.add(self.tab4, text ='LPC Commands')
        self.tabControl.add(self.tab5, text ='UART Commands')

        #TAB 1
        self.entry = tk.Entry(self.tab1, fg='black', bg="white")
        self.button = tk.Button(self.tab1, text="Send Command", command=self.on_button)
        self.label = Label(self.tab1, textvariable=self.info.manual_command_response)


        self.label1 = Label(self.tab1, textvariable=self.stringy)
        self.label2 = Label(self.tab1, textvariable=self.stringy)

        self.entry.grid(row=4,column=40,columnspan=7,padx=10,pady=10)
        self.button.grid(row=4, column=0, padx=10,pady=10)
        self.label.grid(row=5,column=4)
        self.label1.grid(row=6,column=4)
        self.label2.grid(row=7, column=4)

        #TAB 3
        self.button2 = tk.Button(self.tab3, text="Battery Status", command=self.on_status_button)
        self.button2.grid(row=4,column=40,columnspan=7,padx=10,pady=10)

        self.tabControl.grid_columnconfigure(3, weight=1)
        self.tabControl.grid_rowconfigure(3, weight=1)

    def on_button(self) -> None:
        '''
            call back used for sending manual commands
        :param self:
        :return: None
        '''
        temp = self.entry.get()
        send_data(manual_command(temp))
        print(temp)
        self.labek(text = "Mjskdjskdj")
        self.stringy.set("DJSD")

    def on_status_button(self) -> None:
            '''
                call back used for status requests
            :param self:
            :return: None
            '''

print(__name__)
if __name__ == "__main__":
    app = DTerm()
    app.mainloop()


'''

p.s I'm trying to update stringy and label1. and I'm using python 3.9

  • 2
    We do not have to see your entire code, just the main part that is associated with the question. – Delrius Euphoria Sep 17 '21 at 14:26
  • 1
    Why do you create another instance of `Tk` inside `DTerm` as `DTerm` is already inherited from `Tk`? The issue may be due to multiple instances of `Tk`. – acw1668 Sep 17 '21 at 14:38
  • 1
    `tkinter` isn't thread-safe which means that all usage of it must be in a single thread (often the main thread) and this restriction also applies to `StringVar`s. You need to using a queue or something to pass information between the non-GUI threads and the one running the GUI. See my answer to [Freezing/Hanging tkinter GUI in waiting for the thread to complete](https://stackoverflow.com/questions/53696888/freezing-hanging-tkinter-gui-in-waiting-for-the-thread-to-complete). – martineau Sep 17 '21 at 14:40
  • 1
    It may also be due to using multiple instances of `Tk` as @acw1668 says. See [Why are multiple instances of Tk discouraged?](https://stackoverflow.com/questions/48045401/why-are-multiple-instances-of-tk-discouraged) Please provide a [mre] (MRE) if you want more definitive answers. – martineau Sep 17 '21 at 14:41
  • For testing, try changing `self.root = tk.Tk()` to `self.root = self` to see whether it fixes the issue. – acw1668 Sep 17 '21 at 14:51
  • 1
    Please try to reduce this code down to a [mcve]. For example, we probably don't need all six notebook tabs to reproduce the problem. – Bryan Oakley Sep 17 '21 at 14:55
  • Thanks everyone, I didn't fully understand inheritance and why I was having a second instance of TK. That's what it was. – Dyfan Davies Sep 17 '21 at 15:16

0 Answers0