tkinter类ppt的图片浏览组件

引言

这里指的类ppt是指组件主体由图片选择框,原始图片显示框组成,木有自己的编辑功能。

框架

类似PPT,左边是多个图片缩略图的选择框,右边大半部分是原始图片的显示区域。因为原始图片可能会超过显示框,所以显示框必须配备横向和纵向两个滚动条。

那么通过构思得到的组件框架如下:

class ImageView(LabelFrame):
    """一个可以查看多个图片的组件,看起来像ppt"""

    def __init__(self,master,**kw):
        LabelFrame.__init__(self,master,**kw)
        self.imgtext=scrolledtext.ScrolledText(self,state='disabled',cursor='arrow')#缩小照片显示区
        self.imgtext.place(relx=0,rely=0,relwidth=0.21,relheight=1)
        self.imgtext.vbar['width']=10
        self.imgframe=Frame(self,bg='white',relief='flat')
        self.imgback=Text(self.imgframe,bg='white',relief='flat',cursor='arrow',state='disabled')#正常照片显示区
        self.vbar=Scrollbar(self.imgframe,orient='vertical',width=9)
        self.vbar.pack(side='right',fill='y')
        self.vbar.config(command=self.imgback.yview)
        self.hbar=Scrollbar(self.imgframe,orient='horizontal',width=9)
        self.hbar.pack(side='bottom',fill='x')
        self.hbar.config(command=self.imgback.xview)
        self.imgback.pack(side='right',fill='both',expand=True)
        self.imgback.config(xscrollcommand=self.hbar.set, yscrollcommand=self.vbar.set)
        self.imgframe.place(relx=0.21,rely=0,relwidth=0.79,relheight=1)
        self.images={}#存放缩略图与原图信息

在 scrolledtext.ScrolledText 中,可以直接更改滚动条颜色。在这里没有使用颜色参数。

添加图片

为了使组件加载时不用耗费过多时间,设立了专门的函数加入图片并进行显示操作。在添加图片的函数中,图片路径将被作为参数使用。

添加图片分为三个步骤。第一步,先对图片进行尺寸处理,使其能够完整显示在选择框内;第二步,生成与缩略图对应的图片信息,在稍后使用;第三步,显示缩略图,绑定单击信息。

当鼠标经过选项框的图片时,label最好还能够显示橙色(选定颜色)。

方便起见,该组件不对gif进行特殊处理。

#添加图片与生成相对应的图片信息
def append_image(self,img:str):
    path=img
    img=Image.open(img)
    width,height=img.size
    self.update()
    w=self.imgtext.winfo_width()
    h=w*2//3
    eimg=ImageTk.PhotoImage(img)
    img.thumbnail((w,h),Image.ANTIALIAS)
    eimgtk=ImageTk.PhotoImage(img)
    #键:小图片,值:大图片
    self.images[eimgtk]=eimg
    self._append_imagelabel(eimgtk,path)#显示图片

#显示图片并绑定
def _append_imagelabel(self,eimgtk,path):
    #:eimgtk  经过ImageTk.Photoimage处理后的文件。同时是在字典中的缩小图片,键
    #通过label添加图片,让其能够绑定事件
    path=re.findall('.*\\\\(.*)',path)[0]
    self.imgtext['state']='normal'
    imglabel=Label(self.imgtext,relief='groove',image=eimgtk,text=path,compound='bottom')
    imglabel.bind('<Enter>',lambda event:imglabel.config(bg='#EED546'))#显示提醒与离开
    imglabel.bind('<Leave>',lambda event:imglabel.config(bg='#f0f0f0'))
    imglabel.bind('<Button-1>',lambda event:self.change_img(event,eimgtk))
    self.imgtext.window_create('end',window=imglabel)
    self.imgtext.insert('end','\n\n')
    self.imgtext.update()
    self.imgtext['state']='disabled'

显示图片

在图片label被单击后,在原图显示框中显示被选中缩略图的原图

def change_img(self,event,eimgtk):#来自 _append_imagelabel 的单击绑定
    #:eimgtk  缩略图
    self.imgback['state']='normal'
    self.imgback.delete(1.0,'end')
    self.imgback.image_create('end',image=self.images[eimgtk])
    self.imgback['state']='disabled'

完整代码

class ImageView(LabelFrame):
    """一个可以查看多个图片的组件,看起来像ppt"""

    def __init__(self,master,**kw):
        LabelFrame.__init__(self,master,**kw)
        self.imgtext=scrolledtext.ScrolledText(self,state='disabled',cursor='arrow')#缩小照片显示区
        self.imgtext.place(relx=0,rely=0,relwidth=0.21,relheight=1)
        self.imgtext.vbar['width']=10
        self.imgframe=Frame(self,bg='white',relief='flat')
        self.imgback=Text(self.imgframe,bg='white',relief='flat',cursor='arrow',state='disabled')#正常照片显示区
        self.vbar=Scrollbar(self.imgframe,orient='vertical',width=9)
        self.vbar.pack(side='right',fill='y')
        self.vbar.config(command=self.imgback.yview)
        self.hbar=Scrollbar(self.imgframe,orient='horizontal',width=9)
        self.hbar.pack(side='bottom',fill='x')
        self.hbar.config(command=self.imgback.xview)
        self.imgback.pack(side='right',fill='both',expand=True)
        self.imgback.config(xscrollcommand=self.hbar.set, yscrollcommand=self.vbar.set)
        self.imgframe.place(relx=0.21,rely=0,relwidth=0.79,relheight=1)
        self.images={}#存放缩略图与原图信息
    
    def change_img(self,event,eimgtk):
        #:eimgtk  缩略图
        self.imgback['state']='normal'
        self.imgback.delete(1.0,'end')
        self.imgback.image_create('end',image=self.images[eimgtk])
        self.imgback['state']='disabled'
    
    def _append_imagelabel(self,eimgtk,path):
        #:eimgtk  经过ImageTk.Photoimage处理后的文件。同时是在字典中的缩小图片,键
        #通过label添加图片,让其能够绑定事件
        path=re.findall('.*\\\\(.*)',path)[0]
        self.imgtext['state']='normal'
        imglabel=Label(self.imgtext,relief='groove',image=eimgtk,text=path,compound='bottom')
        imglabel.bind('<Enter>',lambda event:imglabel.config(bg='#EED546'))#显示提醒与离开
        imglabel.bind('<Leave>',lambda event:imglabel.config(bg='#f0f0f0'))
        imglabel.bind('<Button-1>',lambda event:self.change_img(event,eimgtk))
        self.imgtext.window_create('end',window=imglabel)
        self.imgtext.insert('end','\n\n')
        self.imgtext.update()
        self.imgtext['state']='disabled'

    def append_image(self,img:str):
        path=img
        img=Image.open(img)
        width,height=img.size
        self.update()
        w=self.imgtext.winfo_width()
        h=w*2//3
        eimg=ImageTk.PhotoImage(img)
        img.thumbnail((w,h),Image.ANTIALIAS)
        eimgtk=ImageTk.PhotoImage(img)
        #键:小图片,值:大图片
        self.images[eimgtk]=eimg
        self._append_imagelabel(eimgtk,path)

效果

在这里插入图片描述
Tin知识库

结语

虽然tkinter提供的原始组件比较少,但是通过组合和添加新的功能函数,同样可以让GUI界面变得丰富。

☀tkinter创新☀

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值