Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
411 views
in Technique[技术] by (71.8m points)

python - Tkinter Label display and disappear when they are created

I'm trying to add new labels (I'll probably switch to buttons but I think the behavior is the same) to a frame after I created it and started the GUI with root.mainloop

Here is the code :

import tkinter as tk
import config
import os
from PIL import ImageTk, Image

class JulieGui():
    dirLabels = []
    def __init__(self, queue):
        self.currentDirDisplayed = False
        root = tk.Tk()
        self.root = root
        self.root.geometry("600x400+0+0")
        self.root.title("Julie")
        self.currentDirLabel = tk.Label(self.root, text="Current dir : ", font="Arial 12", width=600)
        self.currentDirLabel.pack()
        queue.put(self)
        self.run()

def updateDir(self):
    self.currentDir.set(self.currentDirPath)

def runLoop(self):
    self.currentDirLabel.configure(text="CurrentDir : {}".format(config.currentDirPath))
    self.printCurrentDir()
    self.root.after(200, self.runLoop)

def printCurrentDir(self):
    if config.currentDirChanged or not self.currentDirDisplayed:
        print("showing dir")
        self.currentDirDisplayed = True
        nbFiles = 0;
        x = 0
        y = 50
        for f in config.currentDirContent:
            if os.path.isdir(f):
                print("file : {}".format(f))
                print("nb labels : {}".format(len(self.dirLabels)))
                frame = tk.Frame(self.root, width= 500, height = 500, bd = 2, relief = tk.GROOVE)
                frame.place(x = 10, y = 50)
                directory = ImageTk.PhotoImage(Image.open('/home/olivier/git/linuxAssistant/resources/images/directory.jpg'))
                self.dirLabels.append(tk.Label(frame, image = directory, text = "plop", compound = tk.CENTER))
                self.dirLabels[nbFiles].place(x=x, y=y)
                frame.update()
                print("x : {}".format(x))
                print("y : {}".format(y))
                nbFiles += 1
                if nbFiles % 10 == 0:
                    x = 0
                    y += 60
                else:
                    x += 60

def run(self):
    print("starting gui")
    self.root.after(200, self.runLoop)
    self.root.mainloop()
    print("gui started")

def quit(self):
    self.root.after(0, self.root.destroy)

So I'm creating a window with just 1 label and start tkinter with self.root.mainloop(). I'm also using a root.after to continuously update the window with runLoop(self)

This runLoop is calling a printCurrentDir function which should display a label with an icon for each directory found.

the tk.Frame is create is displayed correctly, but the labels disappear as soon as they are created. So when I run the code, I see the first label, then it disappear while the second is displayed... All the labels are created but none on they stays on the screen.

If I don't use frame.update, or self.root.update, the labels are not displayed at all If I replace it with self.root.mainloop() the code stops on it which seems normal.

The list content (config.currentDirContent) and the config.currentDirChanged values are updated when needed by a second thread.

The whole class is started in a threaded function from another class. I'm using the same behavior for another tkinter class with not problem

To make it easier to understand, here are 2 screenshots, after the 1st and 2nd labels added :

1rst label added

Second label added

On the second capture, I should have 2 labels.

2nd problem, my labels are created with an image, and a text (plop for the tests). However, the text is not displayed.

Any idea why I have this behavior and how to fix it?

question from:https://stackoverflow.com/questions/65874024/tkinter-label-display-and-disappear-when-they-are-created

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You created new frame (with one label inside) in each iteration of the for loop inside printCurrentDir() function and put the frames at same position. So the last frame will overlay on top of all the previously created frames. You should create the frame outside the for loop.

Also same image directory is created inside the for loop which should be created outside the for loop as well and change it to instance variable self.directory to avoid garbage collected.

    def printCurrentDir(self):
        if config.currentDirChanged or not self.currentDirDisplayed:
            print("showing dir")
            self.currentDirDisplayed = True
            nbFiles = 0;
            x = 0
            y = 50

            frame = tk.Frame(self.root, width=600, height=600, bd=2, relief=tk.GROOVE)
            frame.place(x=10, y=50)
            self.directory = ImageTk.PhotoImage(file='/home/olivier/git/linuxAssistant/resources/images/directory.jpg')
            for f in config.currentDirContent:
                if os.path.isdir(f):
                    print("file : {}".format(f))
                    print("nb labels : {}".format(len(self.dirLabels)))
                    self.dirLabels.append(tk.Label(frame, image=self.directory, text="plop", compound=tk.CENTER))
                    self.dirLabels[nbFiles].place(x=x, y=y)
                    #frame.update()
                    print("x : {}".format(x))
                    print("y : {}".format(y))
                    nbFiles += 1
                    if nbFiles % 10 == 0:
                        x = 0
                        y += 60
                    else:
                        x += 60

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...