【问题标题】:Multiple Frames, Multiple Buttons and Labels with changing image, Tkinter多帧,多按钮和标签,图像变化,Tkinter
【发布时间】:2020-08-02 20:34:45
【问题描述】:

我正在使用Tkinter 设计一个 GUI。它有许多帧(页面),通过在一个帧中按下一个按钮,该帧被破坏并显示下一帧。每个按钮都有可变图像,所以我需要一个函数来旋转正在显示的每个页面的按钮图像。

我写了下面的代码,照片的地址发生了变化(self.Address in (def counter) of Pagestart class)但我认为button.config不能更新按钮的图像!!!为什么???

(说明:showframe主类函数中的countercounter函数负责更新pagestart中的计数器函数。)

此代码的输出显示一个带有一个按钮的框架,其图像是恒定的并且无法更新。

import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import time
import os
import subprocess as sp
import signal

global counter0, counter1
counter0=0
counter1=0


class Project(tk.Tk):

    def __init__(self, *args, **kwargs):
        
        tk.Tk.__init__(self, *args, **kwargs)      
        
        container = tk.Frame(self)
        container.configure(background="#000000")
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        self.container=container
        self.frames = {}
        for F in ( Pagestart, PageOne):   
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")             
        self.show_frame(Pagestart)
       

    def show_frame(self, cont):
        self.sw = 1000
        self.sh = 1800
        self.cont=cont

        for frame in self.frames.values():
          frame.grid_remove()
        frame = self.frames[cont]
        frame.configure(background="#000000")      
        frame.grid()
        frame.winfo_toplevel().geometry('%dx%d+%d+%d' % (self.sw,self.sh,0,0))

            
        A=Pagestart(parent=self.container, controller=self)
        self.Pagestart=Pagestart
        B=A.button
        
        def countercounter(B):        
            def count1():
              global counter0, counter1
              A.counter()
              if (self.cont==Pagestart):
                  B.after(100,count1)
            count1()
        countercounter(B)
                  
        
    def twoside(self, inputaddress, startframe, stopframe):
        self.input = inputaddress
        self.startframe = startframe
        self.stopframe = stopframe       
        global counter0, counter1
        def count():  
            global counter0, counter1
            if (counter1==1):
                counter0 -=1
            if (counter1==0):
                counter0 += 1
            self.Address=('%s%s' % (str(self.input),str(counter0))+".jpg")
            if (counter0==self.stopframe):
                counter1=1
            if (counter0==self.startframe):
                counter1=0
        count()
           
    def sendAddress(self):
        return self.Address  
           
           
class Pagestart(tk.Frame):
        
    def __init__(self, parent, controller):
        
        tk.Frame.__init__(self, parent)
        self.controller = controller   
        self.ButtonStyle = ttk.Style()
        self.ButtonStyle.configure("Tabedstart.TButton", background="#000000", borderwidth=0)
        self.ButtonStyle.map("Tabedstart.TButton", background=[('selected', "#000000")])
        self.button = ttk.Button(self, style="Tabedstart.TButton", command=lambda: controller.show_frame(PageOne))
        self.button.pack(pady=320)     
        self.counter()      
        
    def counter(self):
      
        self.inputaddress = "/home/pi/Documents/Reference0/"
        self.controller.twoside(self.inputaddress, 0, 138)
        self.Address = self.controller.sendAddress()
        self.photo = Image.open(self.Address)
        self.photo = ImageTk.PhotoImage(self.photo)       
        self.button.image=self.photo
        self.button.config(image=self.photo)
        
class PageOne(tk.Frame):
        
    def __init__(self, parent, controller):
        
        tk.Frame.__init__(self, parent)
        self.controller = controller   
        self.ButtonStyle = ttk.Style()
        self.ButtonStyle.configure("Tabedstart.TButton", background="#000000", borderwidth=0)
        self.ButtonStyle.map("Tabedstart.TButton", background=[('selected', "#000000")])
        self.button = ttk.Button(self, style="Tabedstart.TButton", command=lambda: controller.show_frame(Pagestart))
        self.button.pack(pady=320)     
        self.counter()      
        
    def counter(self):
      
        self.inputaddress = "/home/pi/Documents/Reference1/"
        self.controller.twoside(self.inputaddress, 0, 138)
        self.Address = self.controller.sendAddress()
        self.photo = Image.open(self.Address)
        self.photo = ImageTk.PhotoImage(self.photo)       
        self.button.image=self.photo
        self.button.config(image=self.photo)
        

if __name__ == "__main__":
    app = Project()
    app.mainloop()

【问题讨论】:

  • 所有在函数外部创建的变量都是全局的,所以它们不需要global。我们在函数内部使用global 来通知函数它必须为外部/全局变量赋值而不是创建局部变量。
  • 您不会破坏框架,但您只能使用grid_forget()/grid_remove() 隐藏它。并且再次创建 Pagestart 并不是一个好主意,因为您已经有 Pagestart 的旧实例而不是新实例 - 您可能会更改未显示的新实例中的图像。您会在显示的 Pagestart 的旧实例中看到旧按钮。您应该在 Pagestart 的旧实例中更改图像,您可以使用 frame = self.frames[cont]

标签: python tkinter


【解决方案1】:

您不会破坏框架,但您只能使用 grid_forget()/grid_remove() 隐藏它。

不要创建 Pagestart 的新实例,因为您已经有 Pagestart 的旧实例,它显示为

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

你应该在这个例子中使用 ie 改变图像。

frame.counter()

工作代码:

我使用self.counterself.animation_direction 而不是全局变量counter0counter1

我不使用嵌套函数,因为它的可读性较差。

我使用change_image() 每 100 毫秒更换一次图像

import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk


class Project(tk.Tk):

    def __init__(self, *args, **kwargs):
        
        tk.Tk.__init__(self, *args, **kwargs)      
        
        self.counter = 1
        self.animation_direction = 1  # it will add `+1` to self.counter

        self.sw = 1000
        self.sh = 1800
        
        container = tk.Frame(self)
        container.configure(background="#000000")
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.container = container
        
        self.frames = {}
        
        for F in ( PageStart, PageOne):   
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")
            
        self.show_frame(PageStart)

    def show_frame(self, cont):
        self.cont = cont

        for frame in self.frames.values():
            frame.grid_remove()
          
        frame = self.frames[cont]
        frame.configure(background="#000000")      
        frame.grid()
        frame.winfo_toplevel().geometry('%dx%d+%d+%d' % (self.sw,self.sh,0,0))
        
        #frame.counter()

        self.change_image()
        
    def twoside(self, inputaddress, startframe, stopframe):
        self.input = inputaddress
        self.startframe = startframe
        self.stopframe = stopframe       
        
        self.counter += self.animation_direction

        self.address = '%s%s.jpg' % (self.input, self.counter)
        
        if self.counter == self.stopframe:
            self.animation_direction = -self.animation_direction
        if self.counter == self.startframe:
            self.animation_direction = -self.animation_direction
           
    def get_address(self):
        return self.address  
           
    def change_image(self):
        if self.cont == PageStart:
            self.frames[self.cont].counter()
            self.after(100, self.change_image)
        
           
class PageStart(tk.Frame):  # PEP8: UpperCaseNames for classes
        
    def __init__(self, parent, controller):
        
        tk.Frame.__init__(self, parent)
        self.controller = controller
        
        self.ButtonStyle = ttk.Style()
        self.ButtonStyle.configure("Tabedstart.TButton", background="#000000", borderwidth=0)
        self.ButtonStyle.map("Tabedstart.TButton", background=[('selected', "#000000")])
        
        self.button = ttk.Button(self, style="Tabedstart.TButton", command=lambda: controller.show_frame(PageOne))
        self.button.pack(pady=320)     
        
        self.counter()      
        
    def counter(self):
      
        self.inputaddress = "/home/pi/Documents/Reference0/"
        self.controller.twoside(self.inputaddress, 0, 138)
        
        self.address = self.controller.get_address()  # PEP8: lower_case_names for functions/methods and variables
        self.photo = Image.open(self.address)
        self.photo = ImageTk.PhotoImage(self.photo)
        
        self.button.image = self.photo
        self.button.config(image=self.photo)
        

class PageOne(tk.Frame):
        
    def __init__(self, parent, controller):
        
        tk.Frame.__init__(self, parent)
        self.controller = controller
        
        self.ButtonStyle = ttk.Style()
        self.ButtonStyle.configure("Tabedstart.TButton", background="#000000", borderwidth=0)
        self.ButtonStyle.map("Tabedstart.TButton", background=[('selected', "#000000")])
        
        self.button = ttk.Button(self, style="Tabedstart.TButton", command=lambda: controller.show_frame(PageStart))
        self.button.pack(pady=320)
        
        self.counter()      
        
    def counter(self):
      
        self.inputaddress = "/home/pi/Documents/Reference1/"
        self.controller.twoside(self.inputaddress, 0, 138)
        
        self.address = self.controller.get_address()
        self.photo = Image.open(self.address)
        self.photo = ImageTk.PhotoImage(self.photo)
        
        self.button.image = self.photo
        self.button.config(image=self.photo)
        

if __name__ == "__main__":
    app = Project()
    app.mainloop()

【讨论】:

    猜你喜欢
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    • 2012-11-05
    相关资源
    最近更新 更多