2017-01-09 109 views
5

我不知道是否有一個單選按鈕的標籤文本移動到不同區域的方式,例如低於實際按鈕。如何在Python Tkinter中的按鈕下移動單選按鈕的文本標籤?

下面是使用格被放置,我使用幾個單選按鈕的一個示例:

from tkinter import * 
from tkinter import ttk 


class MainGUI(Frame): 

    def __init__(self, parent): 
     self.parent = parent 
     Frame.__init__(self, parent, background="white") 
     self.mainframe = ttk.Frame(root, padding="8 8 12 12") 
     self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) 
     self.mainframe.columnconfigure(0, weight=1) 
     self.mainframe.rowconfigure(0, weight=1) 
     ttk.Radiobutton(self.mainframe, text="Button 1", value=0).grid(column=1, row=2) 
     ttk.Radiobutton(self.mainframe, text="Button 2", value=1).grid(column=2, row=2) 
     ttk.Radiobutton(self.mainframe, text="Button 3", value=2).grid(column=3, row=2) 
     ttk.Radiobutton(self.mainframe, text="Button 4", value=3).grid(column=4, row=2) 

if __name__ == '__main__': 
    root = Tk() 
    root.geometry("300x100") 
    app = MainGUI(root) 
    root.mainloop() 

下面是當代碼運行幀的圖像:

正如你可以看到默認的是要對按鈕的一面,但我正在尋找一種方式來移動下面的文字,我似乎無法找到這個問題的任何溶液!

謝謝,拉吉

+0

好的問的問題!歡迎來到StackOverflow :)您可能還想參加[tour] :) – geisterfurz007

回答

1

我的想法是嘗試修改ttk.RadioButton的佈局元素或元素的選項。見http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-layouts.html

其元件的佈局似乎由一標籤,即焦點的內部,即內部指示器,即填充內部(參見下面的變量rbLayout)。 Radiobutton.indicator的side選項值保留。 Radiobutton.label的定位選項顯示爲空白。我認爲改變這些選擇可能會得到你想要的。您還必須在ttk.Radiobutton聲明中添加「style = your_customed_stylename」選項。

>>> import tkinter.ttk as ttk 
>>> s = ttk.Style() 
>>> rb = ttk.Radiobutton(None, text='RB1') 
>>> rbClass = rb.winfo_class() 
>>> rbClass 
'TRadiobutton' 
>>> rbLayout = s.layout('TRadiobutton') 
>>> rbLayout 
[('Radiobutton.padding', {'sticky': 'nswe', 'children': [('Radiobutton.indicator', {'sticky': '', 'side': 'left'}), ('Radiobutton.focus', {'children': [('Radiobutton.label', {'sticky': 'nswe'})], 'sticky': '', 'side': 'left'})]})] 
>>> type(rbLayout) 
<class 'list'> 

更新:

  1. 我覺得rbLayout變量顯示,默認情況下 Radiobutton.padding包含兩個子元素,即 Radiobutton.indicator和Radiobutton.focus,以及它們定位Radiobutton.padding左側的 。此外, Radiobutton.focus包含Radiobutton.label。更正我之前對 的解釋。
  2. 爲了達到上述的佈局,我認爲Radiobutton.indicator的 'side'鍵的值應該是'top','sticky'鍵的值應該是 的值'n'。此外,Radiobutton.focus的「邊」鍵應有 值「底部」和「粘」值應爲「S」。
  3. 我創建了一個腳本來實現的改變。見下面的代碼。 但是,它沒有奏效。令人驚訝的是,單選按鈕佈局確實不會改變 。不明白爲什麼它不起作用。

希望有人更瞭解可以解釋爲什麼單選框元素的佈局修正案不改變所需的佈局。

import tkinter as tk 
import tkinter.ttk as ttk 

root = tk.Tk() 
root.geometry("300x100") 

s = ttk.Style() 
m = s.layout('TRadiobutton') 
print('TRadiobutton.Layout : Default') 
print(m , "\n") 

# Change to default Radiobutton.indicator elements 
list(list(m[0])[1]['children'][0])[1]['side'] = 'top' 
list(list(m[0])[1]['children'][0])[1]['sticky'] = 'n' 

# Change to default Radiobutton.focus elements 
list(list(m[0])[1]['children'][1])[1]['side']='bottom' 
list(list(m[0])[1]['children'][1])[1]['sticky']='s' 

print('TRadiobutton.Layout : Amended') 
print(m, "\n") 

frame1 = ttk.Frame(root) 
frame1.grid() 
rb1 = ttk.Radiobutton(frame1, text="Button 1") 
rb1.grid() 

root.rowconfigure(0, weight=1) 
root.columnconfigure(0, weight=1) 

更新2:解決方案

import tkinter as tk 
import tkinter.ttk as ttk 

root = tk.Tk() 
root.geometry("300x100") 

s = ttk.Style() 
s.theme_use('default') 

print('TRadiobutton.Layout : Default') 
print(s.layout('TRadiobutton'), "\n") 

s.layout('TRadiobutton', 
     [('Radiobutton.padding', 
      {'children': 
      [('Radiobutton.indicator', {'side': 'top', 'sticky': ''}), # Just need to change indicator's 'side' value 
      ('Radiobutton.focus', {'side': 'left', 
            'children': 
            [('Radiobutton.label', {'sticky': 'nswe'})], 
            'sticky': ''})], 
      'sticky': 'nswe'})]) 

print('TRadiobutton.Layout : Amended') 
print(s.layout('TRadiobutton'), "\n") 

frame1 = ttk.Frame(root) 
frame1.grid() 
rb1 = ttk.Radiobutton(frame1, text="Button 1") 
rb1.grid() 

root.rowconfigure(0, weight=1) 
root.columnconfigure(0, weight=1) 

Radiobutton with top indicator and bottom label

非常感謝:)來j_4321對我建議的方法他的最新解決方案的構建。我已經實現了它(見上文)我以前的代碼,它的工作原理。我想強調以下幾點:

  1. 我的代碼顯示到的單選框的默認樣式「TRadiobutton」,而不是具有改變佈局創造新風格,佈局做出變化。這種差異的優勢似乎克服了j_4321第二種解決方案的缺點。也就是,它適用於所有ttk主題('clam','alt','default','classic'),而不僅僅是'clam'和'alt'。至少這在我的Linux 16.04平臺上工作。
  2. 我以前的代碼中的錯誤是,我創建了一個新的s.layout()實例(即m = s.layout())並更改了它的佈局,而不是實際更改默認Radiobutton樣式的佈局.layout( 'TRadiobutton')。我從j_4321的解決方案中瞭解到,可以通過更改默認樣式的佈局,作爲元組ttk.Style.layout(小部件的默認樣式名稱)中的第二項添加更改的小部件佈局細節,即ttk。 Style.layout(小部件的默認樣式名稱,例如'TRadiobutton',[更改小部件的佈局細節])
  3. 要更改單選框指示器的位置出現在它的標籤的頂部,變化到Radiobutton.indicator的「側」值到「頂部」 時才需要。對Radiobutton.focus的「side」值的更改對Radiobutton的佈局沒有影響。
+0

您需要將參數中的修改後的佈局傳遞給's.layout':請參閱我的第二個答案以獲取工作示例。 –

+0

@ j_4321非常感謝!我從您的解決方案中學習並更新了我的代碼(請參閱更新2:解決方案)。此外,請注意我的新發現,它克服了您提到的限制(適用於所有ttk.Style主題)和觀察(僅需要更改指標的「側」值)。 –

4

沒有選項來設置一個單選按鈕文本的位置,所以我能想到的最簡單的解決方法是刪除了單選按鈕文字,並把一個標籤在其下方。

此外,我寧願從Tk而不是Frame做出MainGUI類繼承,這樣你就不必創建於if __name__ == '__main__':節根窗口,但它只是一個建議。

from tkinter import * 
from tkinter import ttk 

class MainGUI(Tk): 

    def __init__(self): 
     Tk.__init__(self) 
     self.geometry("300x100") 
     self.configure(background="white") 
     self.mainframe = ttk.Frame(self, padding="8 8 12 12") 
     self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) 
     self.mainframe.columnconfigure(0, weight=1) 
     self.mainframe.rowconfigure(0, weight=1) 
     ttk.Radiobutton(self.mainframe, value=0).grid(column=1, row=2) 
     ttk.Label(self.mainframe, text="Button 1").grid(column=1, row=3, padx=4) 
     ttk.Radiobutton(self.mainframe, value=1).grid(column=2, row=2) 
     ttk.Label(self.mainframe, text="Button 2").grid(column=2, row=3, padx=4) 
     ttk.Radiobutton(self.mainframe, value=2).grid(column=3, row=2) 
     ttk.Label(self.mainframe, text="Button 3").grid(column=3, row=3, padx=4) 
     ttk.Radiobutton(self.mainframe, value=3).grid(column=4, row=2) 
     ttk.Label(self.mainframe, text="Button 4").grid(column=4, row=3, padx=4) 
     self.mainloop() 

if __name__ == '__main__': 
    app = MainGUI() 

Result

備註:拿到這幅畫,我也用一個ttk.Style獲得在linux一個更好的結果。

3

隨着太陽熊建議,另一種方法來獲取按鈕下方的單選按鈕標籤定製TTK風格:

from tkinter import * 
from tkinter import ttk 

class MainGUI(Tk): 

    def __init__(self): 
     Tk.__init__(self) 
     self.geometry("300x100") 
     self.configure(background="white") 
     self.mainframe = ttk.Frame(self, padding="8 8 12 12") 
     self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) 
     self.mainframe.columnconfigure(0, weight=1) 
     self.mainframe.rowconfigure(0, weight=1) 
     style = ttk.Style(self) 
     style.theme_use('clam') 
     # create custom radiobutton style layout 
     style.layout('CustomRadiobutton', 
        [('Radiobutton.padding', 
         {'children': 
          [('Radiobutton.indicator', 
          {'side': 'top', 'sticky': ''}), # changed side from left to top 
          ('Radiobutton.focus', 
          {'children': [('Radiobutton.label', {'sticky': 'nswe'})], 
           'side': 'top', # changed side from left to top 
           'sticky': ''})], 
         'sticky': 'nswe'})]) 
     style.configure('TFrame', background="white") 
     style.configure('CustomRadiobutton', background="white") 
     ttk.Radiobutton(self.mainframe, style='CustomRadiobutton', 
     text="Button 1", value=0).grid(column=1, row=2, padx=4) 
     ttk.Radiobutton(self.mainframe, style='CustomRadiobutton', 
     text="Button 2", value=1).grid(column=2, row=2, padx=4) 
     ttk.Radiobutton(self.mainframe, style='CustomRadiobutton', 
     text="Button 3", value=2).grid(column=3, row=2, padx=4) 
     ttk.Radiobutton(self.mainframe, style='CustomRadiobutton', 
     text="Button 4", value=3).grid(column=4, row=2, padx=4) 
     self.mainloop() 

if __name__ == '__main__': 
    app = MainGUI() 

然而,這並不適用於所有TTK主題的工作。它適用於蛤蜊alt,但給出的按鈕不能用經典默認在Linux中選擇。