簡體   English   中英

無法獲取LabelFrame小部件以顯示在TTK筆記本上(Python 3.5.1)

[英]Cannot get LabelFrame widget to display on ttk notebook (python 3.5.1)

我有一個應用程序,其中ttk筆記本選項卡上的(tkinter)LabelFrame小部件不會自我更新。 在該程序的簡化版本(下面的代碼摘錄)中,小部件甚至不會出現在GUI上。

GUI上的其他所有內容都可以正常工作,包括更新選項卡標題,應用程序標題(和圖標)以及更新所有筆記本電腦選項卡上的Label,Checkbutton和Radiobutton小部件。 使用ttk版本(例如ttk.LabelFrame)創建這些小部件無法解決該問題。 我還嘗試在更新窗口小部件屬性后立即使用“ update_idletasks”(有些人認為這很麻煩)而沒有成功。

在實際的應用程序中,所有GUI小部件的文本都會根據同一GUI上“選擇語言”小部件的狀態而變化(有關詳細信息,請參見: 需要Python / tkinter GUI來動態更新自身(對於多語言GUI) ) 。 已知所有GUI文本值(WidgetName [“ text”]屬性)(包括缺少的LabelFrame)都已正確更新以匹配該小部件的狀態。

筆記本選項卡上的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位PyDev 5.1.2.201606231256的64位Python 3.5.1、64位Win 7 Enterprise SP 1、64位Eclipse Mars 2(Java EE IDE版)。 使用Pydev的“一個用戶”(沒有管理員權限)版本,這需要Microsoft補丁KB2999226(Win10的一部分)才能在Win7上運行。 最終的目標分發是32位Windows應用程序(因此它可以在32和64位Windows上運行)-如果時間允許,請使用Linux。

要記住一個小麻煩:在實際程序中,使用了幾個軟件包。 在每個軟件包中,每個函數都隔離在其自己的文件中。 必須在外部可見(或需要在包文件之間共享)的所有對象(例如tkinter小部件)都在包的_ _ init.py _ _文件中聲明。 必須使用相對導入(例如“ from .Function1 import Function1”)將必須在外部可見的函數顯式導入_ _ init.py _ _。

您的標題具有誤導性,因為您將LabelFrame放置在框架中,而不是直接放置在“筆記本”選項卡上。 您的問題是labelframe沒有出現在其父框架中。 筆記本無關緊要,所有相關代碼都應在發布前刪除。

即使是框架也無關緊要,因為將標簽框架直接放在根中會出現相同的問題。 這是最少的代碼,可以演示問題和解決方案。

from tkinter import Tk
from tkinter import ttk

root = Tk()
lf1 = ttk.LabelFrame(root, text='labelframe 1')
lf2 = ttk.LabelFrame(root, text='labelframe 2', width=200, height=100)
lf1.pack()
lf2.pack()

我在Win 10上使用3.6a2(tk 8.6.4隨附)運行了該程序。 僅lf2是可見的,因為labelframe的默認大小(與框架一樣)為0 x0。非默認大小是由顯式調整大小或由內容引起的。 令人驚訝的是,標簽不算作內容,也不強制使用非默認大小。 我在框架(您的情況)和選項卡上使用labelframe再現了相同的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM