当前位置: 首页 > 知识库问答 >
问题:

如何增强tkinter项目上的窗口大小选择,包括按钮图像作为标签?

魏俊茂
2023-03-14

我目前正在做一个关于python-3. x的小项目,包括一些tkinter资源。我的程序是在屏幕上显示一个目录中包含的图片列表,每张图片都放在一个按钮上,这个按钮是原始图像的六分之一,如果我们点击它,它会在一个新的窗口。原始窗口是由我放在列中的图片量设置的(我可以在代码中选择),我做了一个滚动条,因为我必须处理很多图片。

但这是我的问题,它的工作正常,除了如果我改变窗口大小,比如缩小它,按钮不跟随,他们只是消失在窗口后面,与滚动条。

我不是特别擅长Python,所以我想知道,也许通过像线程一样,我们可以在live中获得窗口大小,然后如果窗口大小低于/优于我们的按钮列,我们可以调整它的大小并改变列的数量重新加载页面,但我将不得不使用多个图像,所以这将需要很多时间。

from tkinter import *
from tkinter.filedialog import *
from tkinter.messagebox import *
from PIL import Image, ImageTk
import tkinter as tk
import glob
import os
import cv2
import copy
import _thread
import time

folder = 'X:/users/Robin/data/dataset-valid/visu/*.jpg'  

a=glob.glob(folder)

fic = "../data/list.txt"

fichObj=open(fic,"w")

p = []

for f in a:
    fichObj.write(f+"\n")
fichObj.close()

class SuperPhoto(object):
        def __init__(self, photo , image):

                self.photo = photo
                temp = cv2.resize(image, (int((self.photo.width())/6) , int((self.photo.height())/6))) 
                red = temp[:,:,2].copy()
                blue = temp[:,:,0].copy()
                temp[:,:,0] = red
                temp[:,:,2] = blue
                temp = Image.fromarray(temp)
                self.miniature = ImageTk.PhotoImage(temp)

        def agrandir(self):
                Newfen=Toplevel() 
                Newfen.geometry("+60+60")
                #self.photo.resize((500,500))


                print(type(self.photo))
                label = Label(Newfen, image=self.photo, width=self.photo.width(), height=self.photo.height())
                label.image = self.photo # keep a reference!
                label.pack()


if os.path.exists (fic):     #os.path utile 
        count = len(open(fic).readlines())    
        print(count)
        #lin = open(fic).readlines()
        #print(lin)


class ScrollableCanvas(Frame):
     def __init__(self, parent, *args, **kw):
        Frame.__init__(self, parent, *args, **kw)

        canvas=Canvas(self,bg='#FFFFFF',width=300,height=300,scrollregion=(0,0,500,500))

        canvas.update_idletasks() 

        vbar=Scrollbar(self,orient=VERTICAL)
        vbar.pack(side=RIGHT, fill=Y)
        vbar.config(command=canvas.yview)

        canvas.config(width=1200,height=700)
        canvas.config(yscrollcommand=vbar.set)
        canvas.pack(side=LEFT,expand=True,fill=BOTH)

        # create a frame inside the canvas which will be scrolled with it
        self.interior = interior = Frame(canvas)
        interior_id = canvas.create_window(0, 0, window=interior, anchor=NW )

        # track changes to the canvas and frame width and sync them,
        # also updating the scrollbar
        def _configure_interior(event):
            # update the scrollbars to match the size of the inner frame
            size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
            canvas.config(scrollregion="0 0 %s %s" % size)
            if interior.winfo_reqwidth() != canvas.winfo_width():
                # update the canvas's width to fit the inner frame
                canvas.config(width=interior.winfo_reqwidth())
        interior.bind('<Configure>', _configure_interior)

        def _configure_canvas(event):
            if interior.winfo_reqwidth() != canvas.winfo_width():
                # update the inner frame's width to fill the canvas
                canvas.itemconfigure(interior_id, width=canvas.winfo_width())
        canvas.bind('<Configure>', _configure_canvas)

class Main_frame(Frame):
    # Init
    def __init__(self, fenetre_principale=None):
        Frame.__init__(self, fenetre_principale)
        self.grid()
        self.scrollable_canvas = ScrollableCanvas(self)
        self.scrollable_canvas.grid(row=1,column=1)         

        nbCol = 4

        for file in a:
                image = Image.open(file)
                photo = ImageTk.PhotoImage(image)
                w = photo.width()
                L.append(int(w/6))
                #print(L)
                sumL = int(sum(L)/nbCol)

                print(sumL)

                p.append(SuperPhoto(photo, cv2.imread(file)))

        for ligne in range(int(count/nbCol)):
                for colonne in range(nbCol):
                        photo = p[ligne * nbCol + colonne]    
                        button = Button(self.scrollable_canvas.interior, image=photo.miniature, command=photo.agrandir)
                        button.grid(row=ligne, column=colonne)


if __name__ == "__main__":
    root = Tk()
    root.title("VISU")
    root.geometry("+0+0")
    L= []    


    interface = Main_frame(fenetre_principale=root)
    root.update_idletasks() 
    print(root.winfo_width())
    print(root.geometry())
    interface.mainloop()

因此,我希望这个程序能像一个经典的目录显示一样工作,当我们调整窗口大小时,列会自动改变,随后会出现滚动条。

如果你有什么解决办法的话,这对我真的很有帮助。。

您可以尝试一下,只需将一些jpeg图片放在一个目录中,并使用目录的链接更改文件夹变量。

提前感谢您的帮助,如果您有任何问题需要更清楚地理解我所说的话,请不要犹豫。

共有1个答案

缪征
2023-03-14

每次调整root窗口的大小时,一个

def resize(event):
    root.update_idletasks()
    #update all image sizes here if needed
    #all widgets can be 're-grided' here based on new width and height of root window

root.bind('<Configure>', resize)

如果要确保无法调整窗口大小,请使用以下命令:

root.resizable(False, False)

 类似资料:
  • 我有一个窗口与列表框,调整大小与彼此。我用网格来做这个。列表框下面有一排按钮,它们当前正在随着窗口移动和调整大小。我希望按钮保持原位,并在窗口和列表框调整大小时保持一致的大小(所以按钮总是保持在列表框的左下角)。 有简单的方法吗?我今天才开始使用Tkinter,所以我可能只是在文档中错过了它,或者可能只是在网格布局上感到困惑。 按钮设置如下: 我已经尝试了所有粘性组合,但那些不调整按钮大小的组合仍

  • 问题内容: 如何从窗口标题栏中删除tkinter图标 问题答案: 在Windows上 步骤1: 使用图标编辑器或类似rw-designer的网站创建透明图标。另存为。 第二步: 在Unix上 类似,但使用图标。

  • 有人知道如何刷新按钮图像图标吗? 问题是: 我正在做一个跳棋游戏,并创建一个GUI。一切正常,包括人工智能,除了我调用我的AI后,我放置了一个移动,结果按钮上没有检查。 单击按钮 单击带有检查器的特定按钮 单击检查器必须去的下一个点 立即呼叫AI以采取行动。 我的按钮上有图像图标,当我点击到下一个点,检查器需要去的地方时,JPanel上的JButton不会在那一刻刷新,而是等待AI移动并完成它的移

  • 我正在做一个画布绘制项目。我将画布转换为图像,然后将该图像另存为“”。巴布亚新几内亚'。我必须右键单击图像并选择“将图像另存为”选项。但我想通过一个按钮提供这个选项。当我点击按钮时,它应该被保存。 任何例子或想法都将不胜感激。 这是一个js函数,用于将画布转换为png。

  • 问题内容: 当我单击他的图像时,我想选择单选按钮,但是它不起作用。这是我尝试过的: 我的两个属性都具有相同的 data =“” 属性:对于图像和输入,单击图像时,是否有任何方法可以检查输入(该收音机)? 谢谢 更新: 我发现一些代码有效,但是仅在图像上单击了三下,因此当单击最后一个脚本时,脚本停止了,无法再次选择第一个或第二个,我不知道为什么…我认为必须取消选中所有单选按钮,然后选中选中的一个按钮

  • 也许有更好的方法来解决这个... 提前感谢!