# Styles and Themes
我的理解是,ttk的動機和吸引力在于它可能組成一個GUI,并且在任何常見的OS(Linux,UNIX,Windows或OS X)上運行時,它看起來都是“正常”的。但是我要做的是 能夠以一種使用戶脫離規范的方式操縱主題和樣式; 我希望能夠擺脫“正常外觀的灰色小世界”的困擾。 不幸的是,似乎存在各種TTK不一致情況,阻礙了該目標。 本節將討論我使用ttk樣式遇到的一些障礙。
這是一個令我困惑的領域。 如果對Linux和MS的默認灰度使用不同的GUI配色方案感興趣,則必須面對樣式。 在獲得Guilherme Polo的大量幫助之前,我無法取得很大進步,這使我到了現在的境地。 我不確定是否找到了實現結果的特別好方法。 因此,我試圖使樣式命令盡可能清晰,以便用戶可以理解我所做的事情并相應地進行更改。 如果用戶知道執行此操作的更好方法,請告訴我,我將嘗試將其合并到將來的版本中。 另外,Maksim Korzh有助于為PNotebook小部件提供樣式編碼。
我對整個樣式和主題業務的期望是,當在不同系統上運行時,一個GUI程序將提供令人愉悅且一致的結果。 我不確定是否已經實現,請參閱本節末尾在不同系統上運行的兩個不同示例的示例。 此外,我希望這種情況在面對不同的配色方案時也會起作用。
首先,我想為用戶自動生成遵循其配色方案的代碼。 考慮以下GUI窗口代碼,其中包含帶有小麥色背景的選項卡式筆記本:
~~~
def __init__(self, master=None):
_bgcolor = 'wheat' # X11 color: #f5deb3
_fgcolor = '#000000' # X11 color: 'black'
_compcolor = '#b2c9f4' # Closest X11 color: 'SlateGray2'
_ana1color = '#eaf4b2' # Closest X11 color: '{pale goldenrod}'
_ana2color = '#f4bcb2' # Closest X11 color: 'RosyBrown2'
font10 = "-family {DejaVu Sans} -size 14 -weight normal -slant roman -underline 0 -overstrike 0"
self.style = ttk.Style()
if sys.platform == "win32":
self.style.theme_use('winnative')
self.style.configure('.',background=_bgcolor)
self.style.configure('.',foreground=_fgcolor)
self.style.configure('.',font=font10)
self.style.map('.',background=
[('selected', _compcolor), ('active',_ana2color)])
master.configure(background=_bgcolor)
self.style.configure('TNotebook.Tab',background=_bgcolor)
self.style.configure('TNotebook.Tab',foreground=_fgcolor)
self.style.map('TNotebook.Tab',background=
[('selected', _compcolor), ('active',_ana2color)])
self.TNotebook1 = ttk.Notebook(master)
self.TNotebook1.place(relx=0.28,rely=0.16,relheight=0.51,relwidth=0.5)
self.TNotebook1.configure(width=300)
self.TNotebook1.configure(takefocus="")
self.TNotebook1_pg0 = ttk.Frame(self.TNotebook1)
self.TNotebook1.add(self.TNotebook1_pg0, padding=3)
self.TNotebook1.tab(0, text="Page 1",underline="-1",)
self.TNotebook1_pg1 = ttk.Frame(self.TNotebook1)
self.TNotebook1.add(self.TNotebook1_pg1, padding=3)
self.TNotebook1.tab(1, text="Page 2",underline="-1",)
~~~
__ init __define中的第一組語句定義默認的GUI顏色和默認的GUI字體。 這些設置直接來自用戶的偏好設置。 我將注釋添加到顏色聲明中,以便用戶對發生的情況有更清晰的了解。 同樣,有幾種不同的方式來指定字體,我認為我使用的字符串格式可能是用戶理解和修改的最清晰的方式。 補色和兩種模擬色是根據網上發現的算法計算得出的。 我已將最接近或確切的X11顏色的名稱作為注釋包含在內。 同樣,如果顏色由X11名稱指定,則注釋中將包含十六進制值。
~~~
_bgcolor = 'wheat' # RGV value #f5deb3
_fgcolor = '#000000' # Closest X11 color: 'black'
_compcolor = '#b2c9f4' # Closest X11 color: 'SlateGray2'
_ana1color = '#eaf4b2' # Closest X11 color: '{pale goldenrod}'
_ana2color = '#f4bcb2' # Closest X11 color: 'RosyBrown2'
font10 = "-family {DejaVu Sans} -size 14 -weight normal -slant roman -underline 0 -overstrike 0"
~~~
下一組語句獲取正在使用的ttk樣式,并為ttk設置背景和前景色的默認值,以及為突出顯示和活動色設置顏色。
~~~
self.style = ttk.Style()
if sys.platform == "win32":
self.style.theme_use('winnative')
self.style.configure('.',background=_bgcolor)
self.style.configure('.',foreground=_fgcolor)
self.style.configure('.',font=font10)
self.style.map('.',background=
[('selected', _compcolor), ('active',_ana2color)])
~~~
這將處理ttk的大多數顏色設置,但不是全部。 我希望ttk中的所有樣式配置都將從“。”對象繼承; 事實并非如此。 請注意,上面的第二和第三行代碼導致在Windows下運行代碼時使用“ winnative”主題。
以下內容修復了“頂級”窗口的背景色。
~~~
top.configure(background=_bgcolor)
top.configure(highlightbackground="wheat")
top.configure(highlightcolor="black")
~~~
由于使用了帶標簽的筆記本,因此我們遇到了ttk“例外”之一-筆記本標簽的顏色。 因此,以下代碼:
~~~
_compcolor = '#b2c9f4' # Closest X11 color: 'SlateGray2'
_ana1color = '#eaf4b2' # Closest X11 color: '{pale goldenrod}'
_ana2color = '#f4bcb2' # Closest X11 color: 'RosyBrown2'
~~~
我遇到了一些代碼,這些代碼旨在計算一種顏色的補色和類似物,并用它們來計算上述顏色。 我還使用類似的代碼將RGB編碼轉換為最接近的X11顏色的名稱,以便用戶可以對顏色有所了解,并在需要時輕松更改它們。
接下來是一種特殊情況,即筆記本選項卡。 在這里,我為選項卡指定了背景色和前景色,因為它們不是從“.” ttk對象繼承的。
~~~
self.style.configure('TNotebook.Tab',background=_bgcolor)
self.style.configure('TNotebook.Tab',foreground=_fgcolor)
~~~
最后,我使所選標簽的顏色與上面定義的背景色互補,并使鼠標下方的標簽的顏色為上方的模擬色之一。 這是一種自動選擇主題顏色的方式,我真的不想這樣做。 似乎有必要競爭這項任務。 我希望用戶能夠從示例中得出他希望進行的更改。
~~~
self.style.map('TNotebook.Tab',background=
[('selected', _compcolor), ('active',_ana2color)])
~~~
上面顯示了我添加的代碼,以使筆記本小部件看起來一致。 對于樹狀視圖小部件,滾動條,帶標簽的框架等,可以看到類似的技巧。同樣,如果您看到更好或更清晰的處理樣式組件的方法,請告訴我。
我在Linux上完成了所有開發工作。 為了說明在不同系統上運行的同一PAGE生成的GUI,讓我展示以下vrex.py的屏幕截圖(vrex是示例部分稍后討論的示例之一):

上圖:在Linux上運行的vrex。 這是我在Linux上使用PAGE構建的。

上圖:在Wine上運行vrex。 除了放大的字體,這是關閉的。

上圖:在Windows XP上運行的vrex。

上圖:使用“ winnative”主題在Windows XP上運行vrex。 除了菜單欄中的背景顏色和sizegrep之外,這看起來還不錯。

上圖:在OS X上運行的vrex。
可以看到,在外觀上存在差異,但總體而言,對于此示例來說,它工作得很好。 之所以幸運,是因為該示例的主要功能是使用平移窗口和滾動文本小部件,它們對于GUI的構建當然很重要。
但是,我創建了另一個名為pptest.py的GUI,可以在examples子目錄中找到該GUI,其中每個包含TNotebook,TButton,TRadiobutton,Tlabel,Label和Button。 如您所見,結果并不理想。

上圖:在Linux上運行的pptest。

上圖:在Wine上運行pptest。

上圖:在Windows XP上運行的pptest。 這相當弱,主要是因為筆記本選項卡的背景和前景不正確。 實際上,如果您運行示例并選擇一個選項卡,則將無法看到前景,它應該是白色,但是當它應該是深色時背景也是白色。 還請注意,TButton,TRadiobutton和標簽都具有與頁面框架的背景色不同的背景色。 這是不幸的,因為雖然可以避免使用TButton和TRadiobutton,但筆記本小部件很重要。 我發現,盡管未在文檔中列出,但在XP下運行時會使用“ xptheme”,它看起來比文檔中未提及的“ winnative”主題還不令人滿意。

上圖:在Windows XP上運行pptest,同時將“ winnative”指定為主題。 就筆記本小部件而言,這看起來是正確的,這比“ xptheme”領先一步。

上圖:在OS X上運行pptest。我的判斷是可以。
我很不明白XP pptest.py示例發生了什么。 顯然,ttk主題正在發生一些非常微妙的事情。 我沒有找到任何有關主題和樣式的足夠文檔,可以幫助我解決這個問題。 我確實注意到,ActiveTcl發行版中的庫目錄具有“ xptheme”和“ winnative”主題,這些主題在文檔中都沒有提及,這可能意味著ttk在XP下的行為可能不同于在其他版本的MS Windows下的行為。 我們看到了本示例的XP和Wine執行與[Vrex](examples.md)之間的區別.
我得出的結論是,如果生成的代碼在Windows上運行生成的GUI時強制使用“ winnative”主題,那會更好。 對于我來說,最好使用具有不正確背景的sizegrip,但比其他方法更好地渲染筆記本小部件。 任何意見,幫助或建議都將受到歡迎。
從上述和類似的經驗來看,由于設計,文檔和/或實現的不一致,我避免使用也作為tk小部件(例如按鈕,標簽,框架,復選框和單選按鈕)實現的ttk小部件,但是使用 筆記本,平移的窗口,進度條和樹狀視圖,因為它們很方便。 我打算繼續研究ttk問題,如果我能夠學習如何避免它們,我一定會這樣做。
- 介紹
- 更新記錄
- X Concepts
- Visual Tcl
- 使用PAGE設計范例
- 項目目錄配置
- Python 2 or Python 3
- Python編碼和UTF-8
- 使用PAGE的簡短說明
- PAGE的狀態
- 安裝
- PAGE界面
- 主菜單
- 子菜單
- 組件工具欄
- 屬性編輯器
- 組件樹
- 綁定操作窗口
- 菜單編輯器
- 首選項窗口
- Python控制臺
- 回調窗口
- 應用窗口
- 顏色對話框
- 顏色
- 雙顯示器
- 默認值和首選項
- Preferences Windows
- Color Preferences
- Font Preferences
- 模塊結構
- 風格和主題
- 使用PAGE
- 命名約定
- 概述
- Toplevel Geometry
- 別名
- 氣球幫助-工具提示
- 選擇和修改組件
- 修改組件位置和尺寸
- 鎖定組件
- 填充容器
- 剪切,復制和粘貼
- Stash and Apply - Propagate Widget Options
- 菜單組件
- 回調函數
- 將事件鏈接到回調函數
- 創建綁定
- 為滾動組件創建綁定
- 定義回調函數
- 查看回調
- 指定字體
- Toplevel Widget
- 相對位置
- Tkinter變量類
- Ttk Widgets
- Scrolled Widgets
- Ttk Notebook and PNotebook
- Ttk Panedwindow
- Ttk Treeview
- Entry
- Ttk Entry
- Ttk Combobox
- Radiobuttons
- 文本和變量的奇異性
- Label
- Listbox
- Spinbox
- Scale and TScale
- TSeparator
- Sizegrip
- Custom Widgets
- Canvas
- 生成,檢查和運行Python GUI
- 創建和保存代碼模塊
- 檢查生成的Python模塊
- 執行Python模塊
- 將生成的Python模塊加載到IDE中
- 具有多個頂級Windows的應用程序
- 修改光標
- 使用圖像
- 動態組件
- 菜單
- 重建
- 自動更新支持模塊
- 重用
- 模板
- 從現有項目中借用組件
- 范例
- 結語