2016-07-07 31 views
0

我有其中TTK筆記本的選項卡上(Tkinter的)LabelFrame部件將不進行自我更新的應用程序。在該程序的一個簡化版本(下面的代碼摘錄)中,小部件甚至不會出現在GUI上。無法獲得LabelFrame小工具來顯示對TTK筆記本(蟒蛇3.5.1)

一切都在GUI上其他正常工作,包括更新標籤的標題,應用程序標題(和圖標),並更新標籤,Checkbutton和單選框部件上的所有筆記本選項卡。使用ttk版本(例如ttk.LabelFrame)創建這些小部件並不能解決問題。在更新小部件屬性後沒有成功,我也嘗試使用「update_idletasks」(有些人認爲這是一個kludge)。

在實際應用中,所有GUI小部件的文本根據同一GUI上的「選擇語言」小部件的狀態而變化(有關詳細信息,請參閱:Need Python/tkinter GUI to dynamically update itself (for a multi-lingual GUI))。衆所周知,包括缺失的LabelFrame在內的所有GUI文本值(WidgetName [「text」]屬性)正在被正確更新以匹配該窗口小部件的狀態。

關於Notebook上的LabelFrame窗口小部件有什麼「特殊」 ?標籤是什麼(可能是簡單)的事情我俯瞰
此外,任何確認/拒絕別人將有助於確定問題是否是唯一的我的系統 - 一個獨特的方法可行,因爲我的機器是由企業IM管理(誰不有不尋常的處理用戶的需求時,像我)的最佳戰績。

感謝


以下是這個問題的一個完整的例子。運行時,LabelFrame小部件(應出現在Tab 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()中的其它模塊的intitialization相是不可用):

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的「一個用戶」(沒有管理權限)版本,這需要微軟補丁KB2999226(Win10的一部分)在Win7上運行。最終目標分佈是32位Windows應用程序(因此它可以在32個& 64位Windows運行) - 並且如果/當時間允許 - Linux操作系統。

有一個輕微的併發症要記住:在實際的程序正在使用的幾個包。在每個包中,每個函數都在其自己的文件內部被隔離。所有對象(例如tkinter小部件)必須在外部可見(或需要在包的文件中共享)在包的_ _ init.py _ _文件中聲明。必須在外部可見的函數通過使用相對導入(例如「from .Function1 import Function1」)顯式導入_ _ init.py _ _。

+0

請閱讀並在https://stackoverflow.com/help/mcve上執行操作。 –

+0

該問題已更新,包括重現問題所需的所有(最小)代碼。 – user1459519

+0

重讀鏈接。最低限度的答案沒有不需要證明問題的線路。它花了我5行。 –

回答

0

由於您將LabelFrame放置在一個框架中,而不是直接放在Notebook選項卡上,因此您的標題具有誤導性。你的問題是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 x 0。非默認大小來自明確尺寸或內容。有點令人驚訝的是,該標籤不算作內容,並且不會強制使用非默認尺寸。我在一個框架(你的情況)和一個選項卡上再現了同樣的結果。

+0

標題是正確的,但我看到是什麼造成了混亂。將筆記本放入選項卡1中的框架內,是我忘記從代碼中刪除的原始代碼中的一個工件。上面發佈的修訂(完整和最小)示例代碼(它包括「交換語言」小部件)省略了該框架。 確認/否認其他人的問題將有所幫助,因爲出於問題的原因,這個問題可能是我的系統所特有的。 – user1459519

+0

確認一下?正如我確認和解釋的那樣,'XLabelFrame = LabelFrame(Tab1Frame)'是不可見的('#NOT APPEARING ON GUI'),因爲它的大小是0 x 0,無論你放在哪裏。 –

+0

謝謝,完全忘了大小默認爲零。將寬度和高度選項添加到LabelFrame可以修復它。奇怪的是,在雙語版本中,LabelFrame小部件不需要這些參數,這可能是因爲小部件不是動態的,默認爲文本參數的寬度)。順便說一句,根據預感,我用等效模塊替換了違規軟件包。這解決了問題,意味着我的包裝結構有問題,) – user1459519