0

I'm trying to source out code for a GUI program. I made a simple test and I cannot change the text value on the GUI, no error and nothing happens. Some issue with the mainloop of Tkinter?

serial.py:

import gui
gui.chiplabel.config(text="A.3f V" )

gui.py:

from Tkinter import *
root = Tk()
chiplabel = Label(root, relief=RIDGE,  width = 9 , text ="Unknown",
                  padx=0, pady=0).grid(row = 0,column=5, sticky =W)
root.mainloop()
nbro
  • 15,395
  • 32
  • 113
  • 196
Marc Pole
  • 29
  • 7
  • You have two problems: 1. `gui.chiplabel is None`, as that's what `grid` returns; and 2. you **never reach** `gui.chiplabel.config(text="A.3f V" )` - and won't until `mainloop` ends (when you close the window, you'll see a `TclError`). Also, what does *"source out"* mean? – jonrsharpe Feb 10 '15 at 16:49
  • I want to create something like a header file in order to have serial code on one module and my gui on the other so i can get a better overview. Since it is possible to alter variables in other modules imported, i wonder how to simply implement a similar solution for creating altering gui texts. – Marc Pole Feb 10 '15 at 16:59
  • What does "source out" mean? – Bryan Oakley Feb 10 '15 at 17:50
  • Just made the question more understandable.But i cant format neither my writing nor my code when writing comments – Marc Pole Feb 10 '15 at 18:03
  • @Bryan Oakley what is your mother tongue ? http://dict.leo.org/ende/index_de.html#/search=source&searchLoc=0&resultOrder=basic&multiwordShowSingle=on – Marc Pole Feb 10 '15 at 18:18
  • @MarcPole that doesn't really answer their question. *"source out"* is certainly not an expression in British (or American, AFAIK) English - do you mean *"outsource"* (get someone else to do something)? *"Refactor"* (rearrange code, generally without affecting its functionality)? – jonrsharpe Feb 10 '15 at 18:20
  • @MarcPole and please **stop putting comments in the question**. Again, if you have a question about something in my answer, *comment on the answer*. In terms of consistent spacing, I am referring to style rather than substance - see e.g. https://www.python.org/dev/peps/pep-0008/. – jonrsharpe Feb 10 '15 at 18:22
  • @markpole: American english is my mother tongue. I asked because I don't think I've ever heard the phrase "source out" in the context of software development. Do you simply mean you want to break your code into multiple (source) files? – Bryan Oakley Feb 10 '15 at 18:50

2 Answers2

4

You have two main problems with your code. It needs to be restructured, and you're making a very common mistake with laying out your widgets.

Organizing your code

The way you have your code structured, your call to configure happens after mainloop exits, and after the widgets have been destroyed. You need to reorganize your code so that the call to mainloop is the last line of code that is executed.

In my opinion this is best accomplished by using classes and objects, but that's not strictly necessary. You simply need to not have any code after you call mainloop.

Laying out the widgets

The problem is this line:

chiplabel = Label( root, relief=RIDGE,  width = 9 , text ="Unknown",  padx=0, pady=0).grid(row = 0,column=5, sticky =W)

In python, when you do x=y().z(), x is given the value of z(). So, when you do chiplabel = Label(...).grid(...), chiplabel is given the value of grid(...). Grid always returns None, so chiplabel will always be None. Because of this, you can't reconfigure it because you've lost the reference to the widget.

The solution is to create the widget and lay out the widget in two steps.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • This doesn't solve the problem, because the relevant line in `serial.py` isn't reached until *after* the window is closed, at which point `gui.chiplabel` doesn't exist any more (causing `TclError: invalid command name ".48254328"`, instead of `AttributeError: 'NoneType' object has no attribute 'config'`). – jonrsharpe Feb 10 '15 at 17:54
  • @jonrsharpe: thanks, jon. You are correct, I've updated my answer. There are actually two problems with the OP's code. – Bryan Oakley Feb 10 '15 at 18:47
  • @Bryan Oakley Thanks for that answer, i got it working the way i wanted it too :) So when i get this right my program calls mainloop at termination ? If not how can the gui be updated ? – Marc Pole Feb 10 '15 at 19:12
  • @MarcPole: `mainloop` should typically be the last line of code in your program. It starts the event loop, which conceptually is the same as calling `update` hundreds of times a second. – Bryan Oakley Feb 10 '15 at 19:47
-1

One way to do this would be to create the UI in a class, e.g.:

import Tkinter as tk  # note don't use wildcard imports

class GUI(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        self.chiplabel = tk.Label(
            self,
            padx=0,
            pady=0,
            relief=tk.RIDGE,
            text="Unknown",
            width=9,
        )  # note alphabetical order and consistent spacing
        self.chiplabel.grid(
            column=5, 
            row=0, 
            sticky=tk.W,
        )  # note grid is separate step

and don't run it in-place, so that you can import the class without running anything. Then your serial.py looks more like:

from gui import GUI

interface = GUI()

interface.chiplabel.config(text="A.3f V")

interface.mainloop()

If you want multiple frames, you could do something like Switching between frames in tkinter menu.

Community
  • 1
  • 1
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • Using a class isn't a solution to the problem. Your code works, but not because you're using a class. It works because you're creating the label and calling `grid` in two separate statements, which the OP is not doing. – Bryan Oakley Feb 10 '15 at 17:53
  • @BryanOakley that is incorrect; have you tested your code? This works because I'm trying to access `chiplabel` *when it still exists*. – jonrsharpe Feb 10 '15 at 17:58
  • @jonrsharpe The german expession is "auslagern" thats what leo gave me as result. I wrote in the second comment of my question what i meant with it. Sorry when i reply to something i try to write it near the question that made mode sense for me. Thanks for the answer but since i already use identation of 2 right now i don´t want to accept pep rules :) – Marc Pole Feb 10 '15 at 18:25
  • @jonrsharpe it can mean having the code separated in separate files (logic wise or just because the code is too long) – Marc Pole Feb 10 '15 at 18:29
  • @jonrsharpe - was refering to to source sth. out, maybe that caused confusion :) source gui code out would be better ? – Marc Pole Feb 10 '15 at 18:34
  • @jonrsharpe: my apologies. I wrote a poorly worded comment. Yes, part of the problem is that the code needs to be better organized. The point I was trying to make was that "use a class" isn't the solution so much as "reorganize your code" is (and the problem with how grid is called). I didn't want a newbie to think they had to use a class to solve the problem. – Bryan Oakley Feb 10 '15 at 18:44