Tkinter<enter>和<leave>事件无法正常工作

2024-09-30 08:27:29 发布

您现在位置:Python中文网/ 问答频道 /正文

请原谅我的代码,但我只是让我的朋友用歌曲信息、每首歌曲的频道信息和歌曲附加的图像等内容自动填充GUI界面。现在我只从Youtube上的播放列表和Soundcloud上的播放列表中抓取。所有这些我都能正常工作,但我对前端开发还不熟悉,这让我陷入了一个可怕的境地,无法为他提出一份像样的申请。我有很多想法,我可以做,但现在我只是创建按钮,每首歌的标题作为文本。Here is an image of my progress.我仍然需要找到一种方法将每个图像附加到on_enter事件的每个按钮上,但这是以后的事情。正如您所看到的,我有一个onéu leave函数被注释掉了。我用它来删除self.image_窗口每次我留下一个按钮。问题是即使是极小的鼠标移动量也会导致窗口被删除并重新创建几十次。如何使其静态,以便当我将鼠标悬停在一个按钮上时,它不会垃圾邮件创建/删除窗口?在

谢谢!在

from Tkinter import *
import json
import os
import webbrowser


class GUIPopulator(Frame):
    def __init__(self, parent):
        Frame.__init__(self)
        self.parent = parent
        self.configure(bg='PeachPuff2')
        self.columnconfigure(20, weight=1)
        self.rowconfigure(30, weight=1)
        self.curtab = None
        self.tabs = {}
        self.pack(fill=BOTH, expand=1, padx=5, pady=5)

        self.column = 0
        self.row = 0

    def on_enter(self, event):

        self.image_window = Toplevel(self)
        self.img_path = os.getcwd() + '/Rotating_earth_(large).gif'
        self.img = PhotoImage(file=self.img_path)

        #self.image_window.minsize(width=200, height=250)
        self.image_window.title("Preview")
        canvas = Canvas(self.image_window, width=200, height=200)
        canvas.pack()
        canvas.create_image(100, 100, image=self.img)
    #def on_leave(self, enter):



    def addTab(self, id):
        tabslen = len(self.tabs)

        tab = {}
        if self.row < 30:
            btn = Button(self, text=id,highlightbackground='PeachPuff2' ,command=lambda: self.raiseTab(id))

            btn.grid(row=self.row, column=self.column, sticky=W+E)

            btn.bind("<Enter>", self.on_enter)

            #btn.bind("<Leave>", self.on_leave)


            tab['id']=id
            tab['btn']=btn



            self.tabs[tabslen] = tab
            self.raiseTab(id)
            self.row +=1
        else:
            self.row = 0
            self.column +=1
            btn = Button(self, text=id,highlightbackground='PeachPuff2' ,command=lambda: self.raiseTab(id))

            btn.grid(row=self.row, column=self.column, sticky=W+E)

            tab['id']=id
            tab['btn']=btn

            self.tabs[tabslen] = tab
            self.raiseTab(id)


    def raiseTab(self, tabid):
        with open(os.getcwd() + '/../PlaylistListener/CurrentSongs.json') as current_songs:
            c_songs = json.load(current_songs)

        print(tabid)
        if self.curtab!= None and self.curtab != tabid and len(self.tabs)>1:
            try:
                #webbrowser.open(c_songs[tabid]['link'])
                webbrowser.open_new('http://youtube.com')
            except:
                pass



def main():
    root = Tk()
    root.title('Playlist Scraper')
    root.geometry("1920x1080+300+300")
    t = GUIPopulator(root)

    with open(os.getcwd() + '/../PlaylistListener/CurrentSongs.json') as current_songs:
        c_songs = json.load(current_songs)

    for song in c_songs:
            t.addTab(song)

    root.mainloop()

if __name__ == '__main__':
    main()

提供的JSON文件示例:

^{pr2}$

Tags: imageselfidjsonondefcolumnroot
1条回答
网友
1楼 · 发布于 2024-09-30 08:27:29

经过一些测试,我想出了一些代码,我认为你可以使用或是你正在寻找的。在

我改变了一些东西,并增加了一些其他的东西。在

首先,我们需要为顶部窗口创建一个占位符,以便稍后在代码中使用。所以在GUIPopulatior__init__部分中添加self.image_window = None。我们将很快讨论这一部分。在

接下来,我将映像路径创建为init上的类属性,如果需要,可以稍后通过更新进行更改。在

接下来,我在init中添加了一个bind(),这将帮助我们即使移动根窗口,也能将{}放在正确的位置。所以我们也将self.parent.bind("<Configure>", self.move_me)添加到__init__部分。在

接下来,我们创建一个方法move_me,我们刚刚为它创建了一个绑定。 它的编写方式只有在self.image_window不等于None时才会生效,这应该可以防止使用self.image_window时出现任何错误,但是我没有创建错误处理来处理用户关闭顶层窗口后发生的情况。这不难,但我想回答手头的主要问题。在

以下是move_me方法:

def move_me(self, event):
    if self.image_window != None:
        h = self.parent.winfo_height() # gets the height of the window in pixels
        w = self.parent.winfo_width() # gets the width of the window in pixels

        # gets the placement of the root window then uses height and width to
        # calculate where to place the window to keep it at the bottom right.
        self.image_window.geometry('+{}+{}'.format(self.parent.winfo_x() + w - 250,
                                                   self.parent.winfo_y() + h - 250))

接下来,我们需要修改on_enter方法来创建顶层窗口,如果out class属性self.image_window等于None,如果它不等于None,那么我们可以使用if语句的else部分来更新图像。在

以下是修改后的on_enter方法:

^{pr2}$

尽管如此,您的代码中还有一些其他问题需要解决,但是这个答案应该会为您指明正确的方向。在

下面是您需要替换的代码部分:

class GUIPopulator(Frame):
    def __init__(self, parent):
        Frame.__init__(self)
        self.parent = parent
        self.configure(bg='PeachPuff2')
        self.columnconfigure(20, weight=1)
        self.rowconfigure(30, weight=1)
        self.curtab = None
        self.tabs = {}
        self.pack(fill=BOTH, expand=1, padx=5, pady=5)

        self.column = 0
        self.row = 0

    def on_enter(self, event):

        self.image_window = Toplevel(self)
        self.img_path = os.getcwd() + '/Rotating_earth_(large).gif'
        self.img = PhotoImage(file=self.img_path)

        #self.image_window.minsize(width=200, height=250)
        self.image_window.title("Preview")
        canvas = Canvas(self.image_window, width=200, height=200)
        canvas.pack()
        canvas.create_image(100, 100, image=self.img)
    #def on_leave(self, enter):

有了这个:

class GUIPopulator(Frame):
    def __init__(self, parent):
        Frame.__init__(self)
        self.parent = parent
        self.configure(bg='PeachPuff2')
        self.columnconfigure(20, weight=1)
        self.rowconfigure(30, weight=1)
        self.curtab = None
        self.image_window = None
        self.img_path = os.getcwd() + '/Rotating_earth_(large).gif'
        self.tabs = {}
        self.pack(fill=BOTH, expand=1, padx=5, pady=5)
        self.parent.bind("<Configure>", self.move_me)
        self.column = 0
        self.row = 0

    def move_me(self, event):
        if self.image_window != None:
            h = self.parent.winfo_height()
            w = self.parent.winfo_width()
            self.image_window.geometry('+{}+{}'.format(self.parent.winfo_x() + w - 250,
                                                       self.parent.winfo_y() + h - 250))

    def on_enter(self, event):

        if self.image_window == None:
            self.image_window = Toplevel(self)
            self.image_window.attributes("-topmost", True)

            h = self.parent.winfo_height()
            w = self.parent.winfo_width()
            self.image_window.geometry('+{}+{}'.format(self.parent.winfo_x() + w - 250,
                                                       self.parent.winfo_y() + h - 250))
            self.img = PhotoImage(file=self.img_path)
            self.image_window.title("Preview")
            self.canvas = Canvas(self.image_window, width=200, height=200)
            self.canvas.pack()
            self.canv_image = self.canvas.create_image(100, 100, image=self.img)

        else:
            self.img = PhotoImage(file= self.img_path)
            self.canvas.itemconfig(self.canv_image, image = self.img)

相关问题 更多 >

    热门问题