0

Imagine that i have a tkinter application with three buttons TestA, TestB, TestC which when pressed show the message "Test Status: Running Test A" (or ...B, ...C) and for some reason i want to create a second script from where when pressed these buttons, three functions of the other script would be called which among many other things that will have to do, at the end should update the config bar of the first (tkinter) script. How could this be achieved, as at any trial i receive errors like the following "AttributeError: module 'testsUnit' has no attribute 'runTestA'"

Here they follow the code for the above described question

First the tkinter gui with no second script which works perfect (Name of script gui_trial.py) (functions runTestA|B|C)

from tkinter import *
from tkinter import ttk
from tkinter import scrolledtext
import time

#Constants
GUI_WIDTH = 300
GUI_HEIGHT = 200

def powerOn():
    statusBar.config(text='Test Status: powerOn')
def powerOff():
    statusBar.config(text='Test Status: powerOff')
def shutdown():
    statusBar.config(text='Test Status: shutDown')

def runTestA():
    statusBar.config(text='Test Status: Running Test A')
def runTestB():
    statusBar.config(text='Test Status: Running Test B')
def runTestC():
    statusBar.config(text='Test Status: Running Test C')

master = Tk()
gui_resolution = str(GUI_WIDTH)+'x'+str(GUI_HEIGHT)+'+0+0'
master.geometry(gui_resolution)
master.title("Trial GUI")

powerOnButton = Button(master, text="Power On", command=powerOn)
powerOnButton.grid(column=1, row=1, pady=5, ipadx=12)
powerOffButton = Button(master, text="Power Off", command=powerOff)
powerOffButton.grid(column=1, row=2, pady=5, ipadx=12)
newTestButton = Button(master, text="Shutdown", command=shutdown)  # showPassTestResult)
newTestButton.grid(column=1, row=3, pady=5, ipadx=12)

testAButton = Button(master, text="Test A", command=runTestA)
testAButton.grid(column=2, row=1, pady=5, ipadx=12)
testBButton = Button(master, text="Test B", command=runTestB)
testBButton.grid(column=2, row=2, pady=5, ipadx=12)
testCButton = Button(master, text="Test C", command=runTestC)
testCButton.grid(column=2, row=3, pady=5, ipadx=12)

statusBar = Label(master, width=25, relief=SUNKEN, text='Test Status: IDLE')
statusBar.grid(column=1, row=4, sticky=SW, padx=10, pady=20)

master.mainloop()

Then the first script again modified for calling a second one (functions runGuiTestA|B|C)

from tkinter import *
from tkinter import ttk
import testsUnit

#Constants
GUI_WIDTH = 300
GUI_HEIGHT = 200

def powerOn():
    statusBar.config(text='Test Status: powerOn')

def powerOff():
    statusBar.config(text='Test Status: powerOff')

def shutdown():
    statusBar.config(text='Test Status: shutDown')

def runGuiTestA():
    #statusBar.config(text='Test Status: Running Test A')
    testsUnit.runTestA()
def runGuiTestB():
    #statusBar.config(text='Test Status: Running Test B')
    testsUnit.runTestB()
def runGuiTestC():
    #statusBar.config(text='Test Status: Running Test C')
    testsUnit.runTestC()

master = Tk()
gui_resolution = str(GUI_WIDTH)+'x'+str(GUI_HEIGHT)+'+0+0'
master.geometry(gui_resolution)
#master.resizable(FALSE, FALSE)
master.title("Trial GUI")

powerOnButton = Button(master, text="Power On", command=powerOn)
powerOnButton.grid(column=1, row=1, pady=5, ipadx=12)
powerOffButton = Button(master, text="Power Off", command=powerOff)
powerOffButton.grid(column=1, row=2, pady=5, ipadx=12)
newTestButton = Button(master, text="Shutdown", command=shutdown)  # showPassTestResult)
newTestButton.grid(column=1, row=3, pady=5, ipadx=12)

testAButton = Button(master, text="Test A", command=runGuiTestA)
testAButton.grid(column=2, row=1, pady=5, ipadx=12)
testBButton = Button(master, text="Test B", command=runGuiTestB)
testBButton.grid(column=2, row=2, pady=5, ipadx=12)
testCButton = Button(master, text="Test C", command=runGuiTestC)
testCButton.grid(column=2, row=3, pady=5, ipadx=12)

statusBar = Label(master, width=25, relief=SUNKEN, text='Test Status: IDLE')
statusBar.grid(column=1, row=4, sticky=SW, padx=10, pady=20)

master.mainloop()

and the second one named testsUnit.py (functions here runTestA|B|C)

import gui_trial

def runTestA():
    gui_trial.statusBar.config(text='Test Status: Running Test A')
def runTestB():
    gui_trial.statusBar.config(text='Test Status: Running Test B')
def runTestC():
    gui_trial.statusBar.config(text='Test Status: Running Test C')
0

1 Answer 1

1

There is circular import issue. Better design is to pass statusBar as an argument of those functions in testsUnity.py:

# no need to import gui_trial
#import gui_trial

def runTestA(statusBar):
    statusBar.config(text='Test Status: Running Test A')
def runTestB(statusBar):
    statusBar.config(text='Test Status: Running Test B')
def runTestC(statusBar):
    statusBar.config(text='Test Status: Running Test C')

Then modify gui_trial.py to pass statusBar to the above functions when they are executed:

...
def runGuiTestA():
    #statusBar.config(text='Test Status: Running Test A')
    testsUnit.runTestA(statusBar) # pass statusBar as an argument
def runGuiTestB():
    #statusBar.config(text='Test Status: Running Test B')
    testsUnit.runTestB(statusBar)
def runGuiTestC():
    #statusBar.config(text='Test Status: Running Test C')
    testsUnit.runTestC(statusBar)
...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.