簡體   English   中英

繼續之前,Python Tkinter檢查單選按鈕狀態

[英]Python Tkinter check radio button state before proceed

我有這個代碼正在工作

import Tkinter as tk
from Tkinter import *


LARGE_FONT= ("Verdana", 12)

class ChangePages(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)
        container.pack()
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        self.frames = {}
        for F in (MainPage, Page01, Page02):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(MainPage)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()

#MainPage
class MainPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)

        button1=Button(self,text='Go To Page 1',fg='blue',font=('Helvetica',26),height=5, width=20,command=lambda: controller.show_frame(Page01)).grid(row=1,column=1)

#Page01
class Page01(tk.Frame):

    def __init__(self, parent, controller):

        option1 = IntVar()
        option2 = IntVar()
        option3 = IntVar()

        tk.Frame.__init__(self, parent)
        f = Frame(self)
        f.pack(side='left')

        label1=Label(f,text='Select options',fg='blue', font=("Arial", 36, "bold"),width=54, relief='solid').grid(row=1,column=1,columnspan=3)

        labelspacing=Label(f,text='Option 1 ',font=("Arial", 18, "bold"),width=20,height=1).grid(row=2,column=1)
        labelspacing=Label(f,text='Option 2 ',font=("Arial", 18, "bold"),width=20,height=1).grid(row=2,column=2)
        labelspacing=Label(f,text='Option 3',font=("Arial", 18, "bold"),width=20,height=1).grid(row=2,column=3)

        buttonoption11=Radiobutton(f, text="Option 1 - A", variable=option1, value=1, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20).grid(row=3,column=1)
        buttonoption21=Radiobutton(f, text="Option 2 - A", variable=option2, value=1, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20).grid(row=3,column=2)
        buttonoption31=Radiobutton(f, text="Option 3 - A", variable=option3, value=1, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20).grid(row=3,column=3)

        buttonoption12=Radiobutton(f, text="Option 1 - B", variable=option1, value=2, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20).grid(row=4,column=1)
        buttonoption22=Radiobutton(f, text="Option 2 - B", variable=option2, value=2, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20).grid(row=4,column=2)
        buttonoption32=Radiobutton(f, text="Option 3 - B", variable=option3, value=2, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20).grid(row=4,column=3)

        buttonoption23=Radiobutton(f, text="Option 2 - C", variable=option2, value=3, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20).grid(row=5,column=2)

        buttonnback=Button(f,text='Back',fg='blue',font=('Helvetica',26),height=1,width=15,command=lambda: controller.show_frame(MainPage)).grid(row=10,column=1)
        buttonnext=Button(f,text='Next',fg='blue',font=('Helvetica',26),height=3,width=15,command=lambda: controller.show_frame(Page02)).grid(row=10,column=2)

#Page02
class Page02(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Page 02!!!", font=LARGE_FONT)
        label.pack(pady=10,padx=10)

        button1 = tk.Button(self, text="Back to Home",
                            command=lambda: controller.show_frame(MainPage))
        button1.pack()

        button2 = tk.Button(self, text="Page 01",
                            command=lambda: controller.show_frame(PageSub35t))
        button2.pack()


#Root loop
app = ChangePages()
app.mainloop()

我想做的是:

當用戶在pag01中按下一個時,我想檢查單選按鈕的狀態。 例如,如果用戶選擇“選項1 -A”和“選項2-C”,我想彈出一條消息,說“你不能選擇2c!只有選擇1B才能選擇2c”而不是讓他轉到第02頁。

我理解你的問題以及你想如何解決它。 但是,從用戶體驗的角度來看,有一種更好的方法可以做到這一點。 除了顯示用戶無法選擇和顯示錯誤消息的用戶選項之外,最好只向用戶顯示他可以選擇的內容 場景示例:

用戶選擇了選項1 -A

單選按鈕選項2 -C變為灰色(禁用)

這是一個演示:

#very bad code
#http://stackoverflow.com/questions/28900100/python-tkinter-check-radio-button-state-before-proceed/28901595#28901595

try:#3.X
    import tkinter as tk
except ImportError:#2.X
    import Tkinter as tk

#use ttk cascade style techniques instead !!!
LARGE_FONT= ("Verdana", 12)

class ChangePages(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)
        container.pack() #use grid everywhere
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        self.frames = {}
        for F in (MainPage, Page01, Page02):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(MainPage)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()

class MainPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)

        button1 = tk.Button(self,text='Go To Page 1',fg='blue',font=('Helvetica',26),height=5, width=20,command=lambda: controller.show_frame(Page01)).grid(row=1,column=1)

class Page01(tk.Frame):

    def __init__(self, parent, controller):

        option1 = tk.IntVar()
        option2 = tk.IntVar()
        option3 = tk.IntVar()

        tk.Frame.__init__(self, parent)
        f = tk.Frame(self)
        f.pack(side='left')

        label1 = tk.Label(f,text='Select options',fg='blue', font=("Arial", 36, "bold"),width=54, relief='solid').grid(row=1,column=1,columnspan=3)

        #not used
        #labelspacing = tk.Label(f,text='Option 1 ',font=("Arial", 18, "bold"),width=20,height=1).grid(row=2,column=1)
        #labelspacing = tk.Label(f,text='Option 2 ',font=("Arial", 18, "bold"),width=20,height=1).grid(row=2,column=2)
        #labelspacing = tk.Label(f,text='Option 3',font=("Arial", 18, "bold"),width=20,height=1).grid(row=2,column=3)

        buttonoption21 = tk.Radiobutton(f, text="Option 2 - A", variable=option2, value=1, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20)
        buttonoption21.grid(row=3,column=2)
        buttonoption22 = tk.Radiobutton(f, text="Option 2 - B", variable=option2, value=2, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20)
        buttonoption22.grid(row=4,column=2)
        buttonoption32 = tk.Radiobutton(f, text="Option 3 - B", variable=option3, value=2, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20)
        buttonoption32.grid(row=4,column=3)

        buttonoption23 = tk.Radiobutton(f, text="Option 2 - C", variable=option2, value=3, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20)
        buttonoption23.grid(row=5,column=2)

        # this entire list is affected by switch_all_button()
        list_conditional = [buttonoption21, buttonoption22, buttonoption32, buttonoption23]


        def switch_button(button, active=True):
            if button is not None:
                button['state'] = {True: tk.NORMAL, False: tk.DISABLED}[active]
                #here you can also unselect

        def switch_all_button(active=True):
            for button in list_conditional:
                switch_button(button, active=active)

        def after_option_command(what_button_should_be_disabled=None):
            def after_option():
                switch_all_button(active=True)
                switch_button(what_button_should_be_disabled, active=False)
            return after_option


        # to update the state of other buttons after 1 is pressed
        # use command=after_option_command(button_x) in the constructor
        buttonoption11 = tk.Radiobutton(f, command=after_option_command(buttonoption23), text="Option 1 - A", variable=option1, value=1, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20)
        buttonoption11.grid(row=3,column=1)
        buttonoption12 = tk.Radiobutton(f, command=after_option_command(), text="Option 1 - B", variable=option1, value=2, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20)
        buttonoption12.grid(row=4,column=1)



        buttonnback = tk.Button(f,text='Back',fg='blue',font=('Helvetica',26),height=1,width=15,command=lambda: controller.show_frame(MainPage)).grid(row=10,column=1)
        buttonnext = tk.Button(f,text='Next',fg='blue',font=('Helvetica',26),height=3,width=15,command=lambda: controller.show_frame(Page02)).grid(row=10,column=2)

class Page02(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Page 02!!!", font=LARGE_FONT)
        label.pack(pady=10,padx=10)

        button1 = tk.Button(self, text="Back to Home",
                            command=lambda: controller.show_frame(MainPage))
        button1.pack()

        button2 = tk.Button(self, text="Page 01",
                            command=lambda: controller.show_frame(PageSub35t))
        button2.pack()


#Root loop
app = ChangePages()
app.mainloop()

您不需要兩次導入tkinter。 使用此語法

try:  # 3.X
    import tkinter as tk
except ImportError:  # 2.X
    import Tkinter as tk

會迫使你使用tk. 每次使用tkinter對象時顯式優於隱式。 它也適用於Python 3。

#Page02
class Page02(tk.Frame):

這是一個無用的評論,因為它沒有增加價值。 代碼質量很差,但這是如何解決它:

  • 關注PEP8
  • 不要使用類作為dicts的鍵
  • 而不是描述主代碼內部的外觀,使用ttkttk.Style()在文件的外部或頂部進行
  • Widget.grid方法返回None,表示

    buttonoption11 = tk.Radiobutton(f, command=after_option_command(buttonoption23), text="Option 1 - A", variable=option1, value=1, indicatoron=0, fg='blue',font=('Helvetica',26),height=1, width=20).grid(row=3,column=1)

    • buttonoption11不是tk.Radiobutton而是None
    • 在任何地方都使用.grid,除非你有充分的理由不這樣做
    • 使用for循環來創建類似的小部件

警告我給出的代碼不是固定的,在應用上面給出的所有提示之前不要使用它

編輯:在評論中按預期工作,閱讀注釋以擴展API

暫無
暫無

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

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