0

I want to make a simple GUI program by Python with Tkinter. I downloaded winPython and extracted its python3.5.2 directory as my python environment.

Then, I used the SpecTcl GUI builder provided in this thread. I built a simple GUI with this builder, the GUI contains only a button and a text area. The builder generates 2 python files, one is "SimpleGUI_ui.py", the other is "SimpleGUI.py." I put both .py files into python3.5.2 directory and run python3.5.2.exe SimpleGUI.py to display the GUI.

Below is the SimpleGUI.py code. Omitted some codes that is not very important.

""" simpleGUI.py --
UI generated by GUI Builder Build 146 on 2016-12-05 22:47:05 from:
C:/Users/User/Downloads/guimaker/simpleGUI.ui
 This file is auto-generated.  Only the code within
'# BEGIN USER CODE (global|class)'
'# END USER CODE (global|class)'
and code inside the callback subroutines will be round-tripped.
The 'main' function is reserved.
"""
from tkinter import *
from simpleGUI_ui import SimpleGUIcd
# BEGIN USER CODE global
# END USER CODE global
class CustomSimpleGUI(SimpleGUI):
    pass

    # BEGIN CALLBACK CODE
    # ONLY EDIT CODE INSIDE THE def FUNCTIONS.
    # _button_1_command --
    # Callback to handle _button_1 widget option -command
    def _button_1_command(self, *args):
        SimpleGUI._text_1.config(text="hello world") # This is useless

    # _text_1_xscrollcommand --
    # Callback to handle _text_1 widget option -xscrollcommand
    def _text_1_xscrollcommand(self, *args):
        pass
    # I omit another yScrollCommand here.

def main():
    # Standalone Code Initialization, DO NOT EDIT
    try: userinit()
    except NameError: pass
    root = Tk()
    demo = CustomSimpleGUI(root)
    root.title('simpleGUI')
    try: run()
    except NameError: pass
    root.protocol('WM_DELETE_WINDOW', root.quit)
    root.mainloop()
if __name__ == '__main__': main()

Below is the SimpleGUI_ui.py code:

""" simpleGUI_ui.py --
UI generated by GUI Builder Build 146 on 2016-12-05 22:47:05 from:
C:/Users/User/Downloads/guimaker/simpleGUI.ui
THIS IS AN AUTOGENERATED FILE AND SHOULD NOT BE EDITED.
The associated callback file should be modified instead.
"""
import tkinter
import os # needed for relative image paths
class SimpleGUI(object):
    _images = [] # Holds image refs to prevent GC
    def __init__(self, root):
        # Widget Initialization
        self._button_1 = tkinter.Button(root,
            text = "_button_1",
        )
        self._text_1 = tkinter.Text(root,
            height = 0,
            width = 0,
        )
        # widget commands
        self._button_1.configure(
            command = self._button_1_command
        )
        self._text_1.configure(
            xscrollcommand = self._text_1_xscrollcommand
        )
        self._text_1.configure(
            yscrollcommand = self._text_1_yscrollcommand
        )
        # Geometry Management
        self._button_1.grid(
            in_    = root,
            column = 1,
            row    = 1,
            columnspan = 1,
            ipadx = 0,
            ipady = 0,
            padx = 0,
            pady = 0,
            rowspan = 1,
            sticky = ""
        )
        self._text_1.grid(
            in_    = root,
            column = 1,
            row    = 2,
            columnspan = 1,
            ipadx = 0,
            ipady = 0,
            padx = 0,
            pady = 0,
            rowspan = 1,
            sticky = "news"
        )
        # Resize Behavior
        root.grid_rowconfigure(1, weight = 0, minsize = 40, pad = 0)
        root.grid_rowconfigure(2, weight = 0, minsize = 40, pad = 0)
        root.grid_columnconfigure(1, weight = 0, minsize = 40, pad = 0)
        root.grid_columnconfigure(2, weight = 0, minsize = 40, pad = 0)

So I followed its comment: modify the callbacks, but not _ui code.

Now the problem I encountered is I couldn't even simply change the text inside _text_1 widget. I tried call SimpleGUI._text_1.config(text="hello world") but it gave me the exception below when I clicked on the button on GUI:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\User\Downloads\python-3.5.2\lib\tkinter\__init__.py", line 1550, in __call__
    return self.func(*args)
  File "simpleGUI.py", line 29, in _button_1_command
    SimpleGUI._text_1.config(text="hello world")
AttributeError: type object 'SimpleGUI' has no attribute '_text_1'

Could anyone please help me, how could I accept the _text_1 widget and configure its text in the callback function so I could make my GUI interactive, and hopefully I could use the same way to access & control any other widgets on GUI. Thanks!

Community
  • 1
  • 1
Mega Chang
  • 249
  • 3
  • 9
  • 1
    Identifiers that begin with an underscore are private, They cannot be accessed outside of the class. You need to create methods that modify them according to your needs, and call these methods from other classes. – DYZ Dec 05 '16 at 16:04
  • Hi @DYZ thanks for your reply, so do you mean, without any modification to `SimpleGUI_ui.py` , there is no way to access GUI widget? Even though comment in the code says the `SimpleGUI_ui.py` should not be edited. – Mega Chang Dec 06 '16 at 08:05

1 Answers1

0

Too bad that I couldn't find a way to access the widget without modifying the SimpleGUI_ui.py code. @DYZ is right, I added a function in SimpleGUI_ui.py and in callback function of SimpleGUI.py I invoked that function, passed self as the 1st parameter, then successfully accessed the widget.

In SimpleGUI_ui.py:

class MailLogChecker(object):
    # other code omitted
    def foo(self):
        self._text_1.insert(1.0, 'abc')

In SimpleGUI.py:

class CustomSimpleGUI(SimpleGUI):
    # other code omitted
    def _button_1_command(self, *args):
        # call like this and pass self to access widgets in UI
        SimpleGUI.foo(self)

I'm still looking for a way that changing only SimpleGUI.py is sufficient to access the UI widget. Anyway, thanks for @DYZ giving me the hint.

Mega Chang
  • 249
  • 3
  • 9