【发布时间】:2023-03-23 15:54:01
【问题描述】:
我有一个应用程序,其中 ttk Notebook 选项卡上的 (tkinter) LabelFrame 小部件不会自行更新。在该程序的一个非常简化的版本中(代码摘录如下),小部件甚至不会出现在 GUI 上。
GUI 上的其他一切都正常工作,包括更新选项卡标题、应用程序标题(和图标)以及更新所有笔记本选项卡上的标签、检查按钮和单选按钮小部件。使用 ttk 版本(例如 ttk.LabelFrame)来创建这些小部件并不能解决问题。我还尝试在更新小部件属性后立即使用“update_idletasks”(有些人认为这是一个杂物)但没有成功。
在实际应用程序中,所有 GUI 小部件的文本都会根据同一 GUI 上“选择语言”小部件的状态而变化(有关详细信息,请参阅:Need Python/tkinter GUI to dynamically update itself (for a multi-lingual GUI))。众所周知,所有 GUI 文本值(WidgetName["text"] 属性),包括缺少的 LabelFrame,都正在正确更新以匹配该小部件的状态。
Notebook 选项卡上的 LabelFrame 小部件有什么“特别”之处吗?我忽略了什么(可能很简单)?
此外,其他人的任何确认/拒绝都将有助于确定问题是否是我的系统所独有的——这是一种独特的可能性,因为我的机器是由公司 IM 管理的(在处理像我这样的不寻常用户的需求时,他们没有最好的记录) .
谢谢
以下是该问题的完整示例。运行时,LabelFrame 小部件(应出现在选项卡 1 的 (0, 0) 处)不会出现。单击“语言”小部件会使其他所有内容以“语言”小部件选择的语言显示文本。
从“LanguageInUse.py”中切换语言的代码:
import sys
c_cedille_lower = "\u00E7" # UTF 8/16 (code page 863?) French character
e_circumflex_lower = "\u00EA"
English = 'English' # string shown on GUI
Francais = 'Fran' + c_cedille_lower + 'ais' # string shown on GUI
DefaultLanguage = Francais
DefaultLanguage = English # comment out this line to use French
user_language = DefaultLanguage # set up language shown on GUI
# Define all language-dependent GUI strings (as "Application-Level" globals)
ComplianceMessage = None
ReportTab1Title = None
ReportTab2Title = None
XCheckbuttonMessage = None
XLabelFrameMessage = None
XLabelMessage = None
XRadioButtonMessage = None
'''=========================================================================='''
def SetGuiLanguage( user_language ) :
global ComplianceMessage, LanguagePrompt
global ReportTab1Title, ReportTab2Title
global XLabelFrameMessage, XCheckbuttonMessage, XLabelMessage, XRadioButtonMessage
if ( user_language == English ):
LanguagePrompt = "Language"
ReportTab1Title = "Message Counts"
ReportTab2Title = "Communications Compliance"
XLabelFrameMessage = "LabelFrame"
XCheckbuttonMessage = "Checkbox"
XLabelMessage = "Label"
XRadioButtonMessage = 'Radiobutton'
ComplianceMessage = "Compliance (engish)"
elif ( user_language == Francais ):
LanguagePrompt = "Langage"
ReportTab1Title = "Comtes de message"
ReportTab2Title = "Compliance Communications"
XLabelFrameMessage = "LabelFrame en " + Francais
XCheckbuttonMessage = "Checkbox en " + Francais
XLabelMessage = "Label en " + Francais
XRadioButtonMessage = "Radiobutton en " + Francais
ComplianceMessage = "Compliance - " + Francais
else:
print (' An unknown user language was specified' )
sys.exit()
return
'''=========================================================================='''
SetGuiLanguage( user_language ) # initialize all tkinter strings at startup
'''========================== End of File ================================'''
来自“SelectReports.py”)构建笔记本的代码:
from tkinter import Checkbutton, Radiobutton, Label, LabelFrame, Frame
from tkinter import ttk
import LanguageInUse
# Locally defined entities importable by other modules (often
# Tkinter Application level objects whose language can be changed)
ComplianceMessageText = None
NotebookFrame = None
XCheckbutton = None
XLabel = None
XLabelFrame = None # NOT APPEARING ON THE GUI
XRadiobutton = None
'''=========================================================================='''
def TabbedReports( ParentFrame ) :
global ComplianceMessageText, NotebookFrame
global SelectReportFrame, UplinkFileWarningText
global XCheckbutton, XLabel, XLabelFrame, XRadiobutton
# Builds the notebook and it's widgits
NotebookFrame = ttk.Notebook( ParentFrame )
NotebookFrame.grid( row = 0, column = 1 )
Tab1Frame = Frame( NotebookFrame )
Tab2Frame = Frame( NotebookFrame )
NotebookFrame.add( Tab1Frame )
NotebookFrame.add( Tab2Frame )
# Create widgets on Tab 1
XLabelFrame = LabelFrame( Tab1Frame ) # NOT APPEARING ON GUI
XCheckbutton = Checkbutton( Tab1Frame )
XLabel = Label( Tab1Frame )
XRadiobutton = Radiobutton( Tab1Frame )
XLabelFrame.grid( row = 1, column = 0 ) # NOT ON GUI
XCheckbutton.grid( row = 1, column = 1 )
XLabel.grid( row = 2, column = 0 )
XRadiobutton.grid( row = 2, column = 1 )
XLabelFrame.configure( text = LanguageInUse.XLabelFrameMessage ) # NOT ON GUI
XCheckbutton.configure( text = LanguageInUse.XCheckbuttonMessage )
XLabel.configure( text = LanguageInUse.XLabelMessage )
XRadiobutton.configure( text = LanguageInUse.XRadioButtonMessage )
# .tab() gives same effect as .configure() for other widget types
NotebookFrame.tab( 0 , text = LanguageInUse.ReportTab1Title )
NotebookFrame.tab( 1 , text = LanguageInUse.ReportTab2Title )
# Create the only widget on Tab 2 (uses other method to specify text)
ComplianceMessageText = Label( Tab2Frame )
ComplianceMessageText.grid( row = 0, column = 0 )
ComplianceMessageText['text'] = LanguageInUse.ComplianceMessage
return
从“ChangeLanguageOnGui.py”更新所有笔记本小部件的代码:
import sys, os
from tkinter import StringVar, Radiobutton, PhotoImage
#from TkinterRoot import root
import LanguageInUse
import SelectReports
'''=========================================================================='''
def ChangeLanguageOnGui() :
SelectReports.XLabelFrame.configure( text = LanguageInUse.XLabelFrameMessage ) # NOT ON GUI
SelectReports.XCheckbutton.configure( text = LanguageInUse.XCheckbuttonMessage )
SelectReports.XLabel.configure( text = LanguageInUse.XLabelMessage )
SelectReports.XRadiobutton.configure( text = LanguageInUse.XRadioButtonMessage )
# .tab() gives the same effect as .configure() for other widget types
SelectReports.NotebookFrame.tab( 0 , text = LanguageInUse.ReportTab1Title )
SelectReports.NotebookFrame.tab( 1 , text = LanguageInUse.ReportTab2Title )
SelectReports.ComplianceMessageText['text'] = LanguageInUse.ComplianceMessage
'''=========================================================================='''
def SetUpGuiLanguage( LanguageFrame ) :
GUI_Language = StringVar( value = LanguageInUse.user_language )
#---------------------------------------------------------------------------
def switchLanguage():
LanguageInUse.user_language = GUI_Language.get()
LanguageInUse.SetGuiLanguage( LanguageInUse.user_language )
ChangeLanguageOnGui()
return
#---------------------------------------------------------------------------
UsingEnglish = Radiobutton( LanguageFrame, indicatoron = False,
variable = GUI_Language,
command = lambda: switchLanguage(),
value = LanguageInUse.English )
UsingFrancais = Radiobutton( LanguageFrame, indicatoron = False,
variable = GUI_Language,
command = lambda: switchLanguage(),
value = LanguageInUse.Francais )
UsingEnglish.grid( row = 0, column = 0 )
UsingFrancais.grid( row = 1, column = 0 )
UsingEnglish.configure( text = LanguageInUse.English )
UsingFrancais.configure( text = LanguageInUse.Francais )
从“TkinterRoot.py”中,使根在任何地方都可导入的代码(显式导入避免了 IntVar() 在其他模块的初始化阶段不可用等问题):
from tkinter import Tk # possibly the worlds shortest useful python module
root = Tk() # makes root an importable "Application Level" global
最后是“A.py”,主线文件:
from TkinterRoot import root
from tkinter import LabelFrame
from tkinter import ttk
import ChangeLanguageOnGui, LanguageInUse, SelectReports, sys
LanguageFrame = None
if __name__ == "__main__":
LanguageChoice = LanguageInUse.English
if ( LanguageChoice == LanguageInUse.English ) :
LanguageInUse.user_language = LanguageChoice
elif ( LanguageChoice == 'Francais' ) :
LanguageInUse.user_language = LanguageInUse.Francais
else :
print( "Unknown Language: " + LanguageChoice )
sys.exit()
mainframe = ttk.Frame( root )
mainframe.grid( row = 0, column = 0 )
LanguageFrame = LabelFrame( mainframe, text = LanguageInUse.LanguagePrompt )
LanguageFrame.grid( row = 0, column = 0 )
ChangeLanguageOnGui.SetUpGuiLanguage( LanguageFrame )
SelectReports.TabbedReports( mainframe )
try:
root.mainloop()
except:
print( 'Exception Occurred' )
sys.exit()
环境是 64 位 Python 3.5.1、64 位 Win 7 Enterprise SP 1、64 位 Eclipse Mars 2(Java EE IDE 版本),运行 64 位 PyDev 5.1.2.201606231256。使用了 Pydev 的“单用户”(无管理员权限)版本,这需要 Microsoft 补丁 KB2999226(Win10 的一部分)才能在 Win7 上运行。最终的目标分发是一个 32 位 Windows 应用程序(因此它可以在 32 位和 64 位 Windows 上运行) - 如果/当时间允许 - Linux。
要记住一个小问题:在实际程序中使用了多个包。在每个包中,每个函数都被隔离在自己的文件中。所有必须在外部可见(或需要在包的文件之间共享)的对象(例如 tkinter 小部件)都在包的 _ _ init.py _ _ 文件中声明。必须在外部可见的函数通过使用相对导入显式导入到 _ _ init.py _ _ 中(例如“from .Function1 import Function1”)。
【问题讨论】:
-
请阅读stackoverflow.com/help/mcve并采取行动。
-
问题已更新,包含重现问题所需的所有(最少)代码。
-
重新阅读链接。一个最小的答案没有不需要证明问题的行。我花了 5 行。
标签: python python-3.x user-interface tkinter ttk