从另一个 python 脚本访问 tkinter GUI
Accessing tkinter GUI from another python script
假设我有一个带有三个按钮 TestA、TestB、TestC 的 tkinter 应用程序,按下这些按钮时会显示消息“测试状态:运行 测试 A”(或 ...B、...C)出于某种原因,我想从按下这些按钮的位置创建第二个脚本,将调用另一个脚本的三个函数,其中包括必须做的许多其他事情,最后应该更新第一个的配置栏( tkinter) 脚本。这是如何实现的,因为在任何试验中我都会收到如下错误:“AttributeError: module 'testsUnit' has no attribute 'runTestA'”
这里他们遵循上述问题的代码
首先是没有第二个脚本的 tkinter gui,它运行完美(脚本名称 gui_trial.py)
(函数 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()
然后再次修改第一个脚本以调用第二个脚本(函数 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()
第二个名为 testsUnit.py(此处运行 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')
存在循环导入问题。更好的设计是将 statusBar
作为 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')
然后修改gui_trial.py
,将statusBar
传递给上面的函数执行时:
...
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)
...
假设我有一个带有三个按钮 TestA、TestB、TestC 的 tkinter 应用程序,按下这些按钮时会显示消息“测试状态:运行 测试 A”(或 ...B、...C)出于某种原因,我想从按下这些按钮的位置创建第二个脚本,将调用另一个脚本的三个函数,其中包括必须做的许多其他事情,最后应该更新第一个的配置栏( tkinter) 脚本。这是如何实现的,因为在任何试验中我都会收到如下错误:“AttributeError: module 'testsUnit' has no attribute 'runTestA'”
这里他们遵循上述问题的代码
首先是没有第二个脚本的 tkinter gui,它运行完美(脚本名称 gui_trial.py) (函数 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()
然后再次修改第一个脚本以调用第二个脚本(函数 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()
第二个名为 testsUnit.py(此处运行 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')
存在循环导入问题。更好的设计是将 statusBar
作为 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')
然后修改gui_trial.py
,将statusBar
传递给上面的函数执行时:
...
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)
...