如何创建一个 tkinter 切换按钮?

10

我正在使用Python 2.7和Tkinter工作于文本编辑器。 现在,我正在尝试添加一个新功能——夜间模式。用户可以通过切换按钮在黑色背景和浅色背景之间切换,切换的过程只需要一次点击。

from Tkinter import *

from tkSimpleDialog import askstring

from tkFileDialog   import asksaveasfilename
from tkFileDialog import askopenfilename

from tkMessageBox import askokcancel

Window = Tk() 
Window.title("TekstEDIT")
index = 0

class Editor(ScrolledText):

    Button(frm, text='Night-Mode',  command=self.onNightMode).pack(side=LEFT)

    def onNightMode(self):
    if index:
        self.text.config(font=('courier', 12, 'normal'), background='black', fg='green')

    else:
        self.text.config(font=('courier', 12, 'normal'))

    index = not index   

然而,在运行代码时,它总是处于夜间模式,并且切换不起作用。请帮忙解决。
源代码:http://ideone.com/IVJuxX
4个回答

4
你可以导入tkinter库(对于Python 2.7,请使用大写字母):
import Tkinter 

Create tkinter objects...

root = tk.Tk()

...和 tkinter 按钮

toggle_btn = tk.Button(text="Toggle", width=12, relief="raised")
toggle_btn.pack(pady=5)
root.mainloop()

现在创建一个名为“toggle”的新命令按钮,以便在按下 relief 属性(凹陷或凸起)时创建“toggle”效果:
def toggle():

    if toggle_btn.config('relief')[-1] == 'sunken':
        toggle_btn.config(relief="raised")
    else:
        toggle_btn.config(relief="sunken")

最后,将此行为应用到您的按钮上:
toggle_btn = tk.Button(text="Toggle", width=12, relief="raised", command=toggle)

我不太懂英语,但我非常擅长Python: 你说的格式正确是什么意思?对于Python 2.7来说很好用!!! 将其复制并粘贴到文本文件中,并将其保存为.py! 在发表不良评论之前请先测试!!! - Albe
在我写这个评论的时候,toggle函数体与def语句缩进相同,因此你无法复制和粘贴它。查看编辑历史记录,你会发现你的原始版本已被其他人编辑以修复缩进问题。 - Bryan Oakley
这是我第一次在Stack Overflow编辑代码时出错了,但我向您保证我是出于善意的,并且这段代码一直都是有效的。下次请私信告知错误,而不是发表负面评论和评判! - Albe
5
这并不是一个负面评论,我只是在陈述一个事实。我不想编辑答案,因为我认为你可能不知道如何正确地格式化它(因为最初是错误的),让你自己修复可以让你学会如何格式化答案。如果你受到了冒犯,我很抱歉。我的唯一目的是帮助你写出更好的答案。 - Bryan Oakley
2
如果您编辑了这个答案,而不是提供另一个包含相同信息的答案,那会更好。 - Bryan Oakley
显示剩余2条评论

2

背景和前景仅在if条件语句中设置。你需要在else条件语句中也进行设置:

def onNightMode(self):
    if index:
        self.text.config(font=('courier', 12, 'normal'), background='black', fg='green')

    else:
        self.text.config(font=('courier', 12, 'normal'))

    index = not index

i.e.,

else:
    self.text.config(font=('courier', 12, 'normal'), background='green', fg='black')

3
UnboundLocalError错误是由于对index赋值使其默认成为局部变量,而实际上需要引用全局变量。快速修复的方法是在函数内添加语句global index。但更好的解决方法是避免使用可变全局变量,而是将index作为实例属性self.index - unutbu

1

Albe的回答是不错的,但它有一些不良的编码实践。

按照相同步骤:

Import Tkinter as tk 
top = tk.TK()

定义你的函数并使其适用于任何按钮,而不是硬编码到你可能使用的特定按钮上。

def toggle(button: tk.Button):
    if button.config('relief')[-1] == 'sunken':
        button.config(relief="raised")
    else:
        button.config(relief="sunken")

然后创建并打包您想要的所有切换按钮。
toggleButton = tk.Button(text="Toggle", width=12, relief="sunken",
command =lambda:toggle(toggleButton))
toggleButton.pack(pady=5)
top.mainloop()

这种方法有两个优点。首先,重复创建按钮对象会导致代码出现错误。其次,将按钮硬编码到特定的切换函数中是不可扩展的。使用这种解决方案可以使代码具有可重用性,并且很容易添加。例如,将最后一个块替换为:

for _ in range(4):
    b = tk.Button(text="Toggle", width=12, relief="sunken")
    b['command']= lambda a=b:toggle(a)
    b.pack(pady=5)

现在您可以获得4个切换按钮,无需任何额外的功能或复制/粘贴。

1
这里是一个代码片段,如果你需要的话可以帮助你进行切换按钮动画。当然,你只需要添加你想要执行的函数,这取决于你。
'''
    import tkinter as tk

    # --- functions ---

    def move(steps=10, distance=0.1):
        if steps > 0:
            # get current position
            relx = float(frame.place_info()['relx'])

            # set new position
            frame.place_configure(relx=relx+distance)

            # repeate it after 10ms
            root.after(10, move, steps-1, distance)

    def toggle(event):
        if button["text"] == "Yes":
            move(25, 0.02)  # 50*0.02 = 1
            button["text"] = "No"
            print("Clicked on yes")
        elif button["text"] == "No":
            move(25, -0.02)
            button["text"] = "Yes"
            print("Clicked on no")


    # --- main --

    root = tk.Tk()

    frame = tk.Frame(root, background='red')
    frame.place(relx=0, rely=0, relwidth=0.5, relheight=1)

    # to center label and button
    #frame.grid_columnconfigure(0, weight=1)
    #frame.grid_rowconfigure(0, weight=1)
    #frame.grid_rowconfigure(3, weight=1)




    button = tk.Button(frame, text='Yes',width=5,height=1)
    button.place(relx=0.25,rely=0.5,relwidth=0.5, relheight=0.1)
    button.bind("<Button-1>",toggle)


    root.mainloop()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接