Tkinter app structure

R

Richard Lewis

Hi there,

I've just started my first project with Tkinter.

I've already coded all the data handling classes and have a nice
interface to work with (it happens to be a wrapper around the DOM of a
large(ish) XML document but thats probably not important ;-)

I'm new to Tkinter so I've started in a fairly random place: the main
menu. I noticed that the event mechanism was based on callbacks so, in a
flash of inspiration, I decided to create a new module called
'commands.py' which would contain all my callback methods (meaning I
could use them for a toolbar as well, if I ever add one) and which acts
as an intermediary between the Tkinter classes and my data hanlding
classes.

I've also created a 'main.py' module which holds the Tk object (called
'root'), the top level data object (called 'data') and the main UI
object (called 'mwnd', an instance of a class inherited from Frame
called 'MainWindow').

* The main.py module imports:

from dataclasses import *
from mainwindow import *
from Tkinter import *

* The mainwindow.py module imports:

from Tkinter import *
from commands import *

* The commands.py modules imports:

import main
import tkMessageBox

* And the dataclasses.py module imports only unrelated modules

This set up should allow me to be able to access main.data and main.root
from the commands.py module and the command callback functions (defined
in commands.py) from mainwindow.py.

main.py looks like this:
====================================
1: from dataclasses import *
2: from mainwindow import *
3: from Tkinter import *
4:
5: data = Database()
6:
7: root = Tk()
8: mwnd = MainWindow(root)
9: root.mainloop()
====================================

However, when I execute it I get the following error:

Traceback (most recent call last):
File "./main.py", line 2, in ?
from mainwindow import *
File "mainwindow.py", line 2, in ?
from commands import *
File "commands.py", line 4, in ?
import main
File "main.py", line 8, in ?
mwnd = MainWindow(root)
NameError: name 'MainWindow' is not defined

(where 'mainwindow.py' line 2 is "from commands import *", commands.py
line 4 is "import main" and the name "MainWindow" is the name of the
class defined in the mainwindow.py module)

Whats going wrong? Is it a 'circular import'? Is there a better way that
I could organise these modules?

Cheers,
Richard
 
C

Christopher Subich

Richard said:
Hi there,

I've just started my first project with Tkinter.
This set up should allow me to be able to access main.data and main.root
from the commands.py module and the command callback functions (defined
in commands.py) from mainwindow.py.
Whats going wrong? Is it a 'circular import'? Is there a better way that
I could organise these modules?

Yes, this looks like a circular import to me.

Remember, though, that an import statement in Python isn't completely
analagous to a #include statement in C; because of dynamic typing and
the general guideline of duckitude ("if it walks like a duck and quacks
like a duck..."), you usually don't /need/ to have circular imports.

With the presumption that data = Database() is a mutable object, in
that you interact with it normally and don't reassign it anywhere in
your program, why not just pass data as a parameter to
MainWindow.__init__? Likewise, MainWindow can call commands with
root/data as parameters -- you could even organize your commands into
an instantiated class, and have the CommandClass take both of these as
__init__ arguments. In the program (MUD Client) that I'm working on, I
have a vaguely similar dependency between interface-agnostic backend
code and the in-development TKinter interface; by wrapping everything
except main() and a few constants inside instantiated classes, I think
I've mostly avoided circular imports.

If you really, truly need data to be a global variable, you could
possibly put it inside its own module, and instantiate it via
data_module.data = Database() from main. But that's really ugly, and
I'm not 100% sure that it'd work -- I've never had need to try it, and
am writing this off-the-cuff.

But take this advice all with a lagish grain of iodized NaCl, since I'm
a rank newbie at Python.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,241
Messages
2,571,223
Members
47,856
Latest member
mmorais

Latest Threads

Top