admin管理员组

文章数量:1402469

Basic question on hierarchy:

I have a simple top level GUI with no functionality, 2 each of just labels, entry boxes & buttons in 2 separate frames, but want the functionality to be added from a sub-folder called "modules" and I import the functions with "import modules.func01" The modules folder has the (empty) init.py and the func_01.py files

Is it possible to do this, that is, declare the button without a command and add the command with a config statement in the func_01 file?

I'm getting error that the button is not defined.

My project is to build a GUI with 6 or so frames, each frame to have several entry boxes for time, power etc, an add button for each frame, then an overall "build" button that takes the data that has been added from all the frames and writes out a file from the entered data after some manipulation etc. I'd like to keep the GUI as one file and the functions for each frame in separate files etc.

NOTE: I have successfully built the project as one big file (not ideal, but I learned a lot doing it, but now to do it better), but that makes updates & maintenance not so easy.

Any advice/help is appreciated.

#  GUI.py top level file

import tkinter as tk
import modules.func_01

root = tk.Tk()
root.geometry("700x500")
#root.resizable(False, False) 
root.title("Test GUI only top file.")

frame_01 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)
frame_02 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)
frame_03 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)

frame_01.grid(row=0, column=0)
frame_02.grid(row=1, column=1)
frame_03.grid(row=2, column=0, columnspan=2)


label_01 = tk.Label(frame_01, text = "Frame_01, Enter text below!").grid(row=0, column=0)
label_02 = tk.Label(frame_02, text = "Frame_02, Enter text below!").grid(row=0, column=0)

ent_01   = tk.Entry(frame_01, width = 20).grid(row=1, column=0)
ent_02   = tk.Entry(frame_02, width = 30).grid(row=1, column=0)

but_01   = tk.Button(frame_01, text="Press me No 1 (Entry t0 text box).").grid(row=2, column=0)
but_02   = tk.Button(frame_02, text="Press me No 2 (Entry t0 text box).").grid(row=2, column=0)

text_box = tk.Text(frame_03, height = 15, width = 60, padx=10,pady=10).grid(row=0, column=0) 

root.mainloop()
# func_01.py file in modules sub-folder
def get_display_ent_01():
    # get the text from entry 01 in frame_01:
    # display in the fetched text in frame_03 text box
    # code not yet written
    pass
    
but_01.config(command = get_and_display_ent_01)

This does not work. Is what I'm trying possible? If you hadn't guessed, I'm a bit of a python newbie.

Basic question on hierarchy:

I have a simple top level GUI with no functionality, 2 each of just labels, entry boxes & buttons in 2 separate frames, but want the functionality to be added from a sub-folder called "modules" and I import the functions with "import modules.func01" The modules folder has the (empty) init.py and the func_01.py files

Is it possible to do this, that is, declare the button without a command and add the command with a config statement in the func_01 file?

I'm getting error that the button is not defined.

My project is to build a GUI with 6 or so frames, each frame to have several entry boxes for time, power etc, an add button for each frame, then an overall "build" button that takes the data that has been added from all the frames and writes out a file from the entered data after some manipulation etc. I'd like to keep the GUI as one file and the functions for each frame in separate files etc.

NOTE: I have successfully built the project as one big file (not ideal, but I learned a lot doing it, but now to do it better), but that makes updates & maintenance not so easy.

Any advice/help is appreciated.

#  GUI.py top level file

import tkinter as tk
import modules.func_01

root = tk.Tk()
root.geometry("700x500")
#root.resizable(False, False) 
root.title("Test GUI only top file.")

frame_01 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)
frame_02 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)
frame_03 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)

frame_01.grid(row=0, column=0)
frame_02.grid(row=1, column=1)
frame_03.grid(row=2, column=0, columnspan=2)


label_01 = tk.Label(frame_01, text = "Frame_01, Enter text below!").grid(row=0, column=0)
label_02 = tk.Label(frame_02, text = "Frame_02, Enter text below!").grid(row=0, column=0)

ent_01   = tk.Entry(frame_01, width = 20).grid(row=1, column=0)
ent_02   = tk.Entry(frame_02, width = 30).grid(row=1, column=0)

but_01   = tk.Button(frame_01, text="Press me No 1 (Entry t0 text box).").grid(row=2, column=0)
but_02   = tk.Button(frame_02, text="Press me No 2 (Entry t0 text box).").grid(row=2, column=0)

text_box = tk.Text(frame_03, height = 15, width = 60, padx=10,pady=10).grid(row=0, column=0) 

root.mainloop()
# func_01.py file in modules sub-folder
def get_display_ent_01():
    # get the text from entry 01 in frame_01:
    # display in the fetched text in frame_03 text box
    # code not yet written
    pass
    
but_01.config(command = get_and_display_ent_01)

This does not work. Is what I'm trying possible? If you hadn't guessed, I'm a bit of a python newbie.

Share Improve this question asked Mar 21 at 14:09 KevPKevP 216 bronze badges 2
  • I've now moved the command to the button declaration: command = modules.func_01.get_display_ent_01. This moved me on one step, but now it says ent_01 is not declared because it's in the top level GUI file. I seem to be going round in circles. – KevP Commented Mar 21 at 14:41
  • Pass the entry object to the function. command=lambda: func(ent_01) – 8349697 Commented Mar 22 at 9:21
Add a comment  | 

1 Answer 1

Reset to default 1

Either use object-oriented programming(declare classes) and make but_01 a static variable. Or pass this but_01 as an argument to the function get_display_ent_01() when you call it.

Anyways better would be that you add command where you have declared but_01. Since you are importing func_01.py module, you can write as-

SOLUTION 1


import tkinter as tk
import modules.func_01

root = tk.Tk()
root.geometry("700x500")
#root.resizable(False, False) 
root.title("Test GUI only top file.")

frame_01 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)
frame_02 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)
frame_03 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)

frame_01.grid(row=0, column=0)
frame_02.grid(row=1, column=1)
frame_03.grid(row=2, column=0, columnspan=2)


label_01 = tk.Label(frame_01, text = "Frame_01, Enter text below!").grid(row=0, column=0)
label_02 = tk.Label(frame_02, text = "Frame_02, Enter text below!").grid(row=0, column=0)

ent_01   = tk.Entry(frame_01, width = 20).grid(row=1, column=0)
ent_02   = tk.Entry(frame_02, width = 30).grid(row=1, column=0)

but_01   = tk.Button(frame_01, text="Press me No 1 (Entry t0 text box).",command=modules.func_01.get_display_ent_01).grid(row=2, column=0)
but_02   = tk.Button(frame_02, text="Press me No 2 (Entry t0 text box).").grid(row=2, column=0)

text_box = tk.Text(frame_03, height = 15, width = 60, padx=10,pady=10).grid(row=0, column=0) 

root.mainloop()



# func_01.py file in modules sub-folder
def get_display_ent_01():
    # get the text from entry 01 in frame_01:
    # display in the fetched text in frame_03 text box
    # code not yet written
    pass
    
SOLUTION 2

#Main_module.py

import tkinter as tk
import modules.func_01

class A:

    but_01=''

    root = tk.Tk()
    root.geometry("700x500")
    #root.resizable(False, False) 
    root.title("Test GUI only top file.")

    frame_01 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)
    frame_02 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)
    frame_03 = tk.Frame(root, relief="ridge", bd=4, padx=5,pady=5)

    frame_01.grid(row=0, column=0)
    frame_02.grid(row=1, column=1)
    frame_03.grid(row=2, column=0, columnspan=2)


    label_01 = tk.Label(frame_01, text = "Frame_01, Enter text below!").grid(row=0, column=0)
    label_02 = tk.Label(frame_02, text = "Frame_02, Enter text below!").grid(row=0, column=0)

    ent_01   = tk.Entry(frame_01, width = 20).grid(row=1, column=0)
    ent_02   = tk.Entry(frame_02, width = 30).grid(row=1, column=0)

    A.but_01   = tk.Button(frame_01, text="Press me No 1 (Entry t0 text box).").grid(row=2, column=0)
    but_02   = tk.Button(frame_02, text="Press me No 2 (Entry t0 text box).").grid(row=2, column=0)

    text_box = tk.Text(frame_03, height = 15, width = 60, padx=10,pady=10).grid(row=0, column=0) 

    root.mainloop()






# func_01.py file in modules sub-folder

import importlib


def get_display_ent_01():
    # get the text from entry 01 in frame_01:
    # display in the fetched text in frame_03 text box
    # code not yet written
    pass


mohdul = importlib.import_module("Main_module")              #Avoids circular import. Imports during runtime
mohdul.A.but_01.config(command = get_display_ent_01)

本文标签: Splitting python program into GUI top and submodulesStack Overflow