我想将一个函数绑定到 tkinter 中的一个标签,这让我很困惑

问题描述

我仍然在和我一起学习

程序基本说明: 使用 python3 和 tkinter 模块,我正在制作一个小的 GUI 来学习基础知识。 GUI 中有一个按钮,想法是当您单击该按钮时,会在 gui 内的另一个小部件(在本例中为标签)中显示随机文本(来自 txt 文件)。

我可以让程序从文本文件提取随机经文,并在 shell 中打印它们,但不能在 gui 小部件中打印。

代码需要 2 个文件,.py 和 .txt

我将它们上传到了一个 github 存储库,因此可能更容易了解那里的程序

Link to the project on github

但是,如果这样更方便,我会将 .py 代码在这里,但如果没有 txt 文件它就无法运行。

import random
import tkinter as tk
from tkinter import *

class MainApplication(tk.Frame):
    def __init__(self,parent):
        tk.Frame.__init__(self,parent)  
        self.parent = parent
        
    def random_line():
        line_num = 0
        selected_line = ''
        with open('dhammapada.txt') as f:
            while 1:
                line = f.readline()
                if not line: break
                line_num += 1 
                if random.uniform(0,line_num) < 1:
                    selected_line = line
        return(selected_line.strip())         


    def print_a_verse():
        print('\n',random_line())

    btn_result = Button(self,fg='Gold',text='New Verse',bg='Black',font='freesansbold,16',command=print_a_verse) #textvariable=cvt_to,fg='Blue')
    btn_result.pack(fill=X,side=BottOM)#fill=BOTH,expand=1)

    lbl_one = Label(self,bg='DarkGrey',fg='White',text='Dhammapada',22')
    lbl_one.pack(fill=BOTH,expand=1)

    lbl_thr = Label(self,text='The Dhammapada \nSiddartha Gautama - Buddha',18')
    lbl_thr.pack(fill=BOTH,expand=1)

    lbl_two = Label(self,fg='Grey')
    lbl_two.pack(fill=BOTH,expand=1)


if __name__ == "__main__":
    root = tk.Tk()
    root.minsize(400,400)
    #root.configure(bg='Black')
    root.title('Python - Dhammapada Verses')
    MainApplication(root).pack(side="top",fill="both",expand=True)
    root.mainloop()

几年前,当我第一次接触编码时,我开始了这个 repo,当时我在网上自学,然后因为非常严重的癫痫症,我不得不放弃坐在屏幕前几个小时,所以停止了这一切。我想那是 2016 年。这是我从那以后看的第一个程序,这本书的主题多年来对我帮助很大。

我希望有人能指出我正确的方向。我可能已经把整件事搞砸了!

编辑:

class Person:
  def __init__(self,name,age):
    self.name = name
    self.age = age

解决方法

试试这个:

import tkinter as tk
from tkinter import *

class MainApplication(tk.Frame):
    def __init__(self,parent):
        tk.Frame.__init__(self,parent)
        self.parent = parent

        btn_result = Button(self,fg='Gold',text='New Verse',bg='Black',font='freesansbold,16',command=self.print_a_verse) #textvariable=cvt_to,fg='Blue')
        btn_result.pack(fill=X,side=BOTTOM)#fill=BOTH,expand=1)

        lbl_one = Label(self,bg='DarkGrey',fg='White',text='Dhammapada',22')
        lbl_one.pack(fill=BOTH,expand=1)

        lbl_thr = Label(self,text='The Dhammapada \nSiddartha Gautama - Buddha',18')
        lbl_thr.pack(fill=BOTH,expand=1)

        lbl_two = Label(self,fg='Grey')
        lbl_two.pack(fill=BOTH,expand=1)

    def random_line(self):
        return "testing text" # Just for testing
        line_num = 0
        selected_line = ''
        with open('dhammapada.txt') as f:
            while 1:
                line = f.readline()
                if not line: break
                line_num += 1
                if random.uniform(0,line_num) < 1:
                    selected_line = line
        return(selected_line.strip())

    def print_a_verse(self):
        print(self.random_line())


if __name__ == "__main__":
    root = tk.Tk()
    root.minsize(400,400)
    #root.configure(bg='Black')
    root.title('Python - Dhammapada Verses')
    MainApplication(root).pack(side="top",fill="both",expand=True)
    root.mainloop()

我将所有小部件定义移到您的 __init__ 方法中,并在适当的地方添加了 self 以确保它不会引发任何错误。我还建议您查看快速的面向对象编程教程。

,

我会首先从文本文件中读取一次,然后将所有经文存储在一个列表中。现在编写代码的方式是,每次调用 random_line 时,都是在打开和关闭文件,这似乎没有必要。

您选择随机行的方法并不完美,也可以简化 - 您逐行通读文件,并根据某个随机数是否低于某个随机数,偶尔决定重新分配 selected_line任意阈值。这有几个问题 - 没有机制可以防止 selected_line 被多次覆盖(这是不必要的)。也不能保证 selected_line 会从其初始空状态被覆盖。此外,随机数是通过 random.uniform(0,line_num) 生成的 - 由于 line_num 随每次迭代增加,随机数低于阈值的可能性随着每次迭代而减小。因此,更靠近文件顶部的行更有可能被选中。

解决方案是简单地使用 random.choice 从所有可能的诗句列表中随机选择一个诗句:

import tkinter as tk


class Application(tk.Tk):

    def __init__(self,*args,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        self.title("Random Verse")
        self.geometry("256x256")
        self.resizable(width=False,height=False)

        self.button = tk.Button(self,text="Click",command=self.on_click)
        self.button.pack()

        self.label = tk.Label(self,text="",wraplength=200)
        self.label.pack()

        self.verses = self.get_verses("dhammapada.txt")

    def get_verses(self,file_name):
        with open(file_name,"r") as file:
            verses = file.read().splitlines()
        return verses

    def on_click(self):
        from random import choice
        self.label["text"] = choice(self.verses)


def main():
    Application().mainloop()
    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())