带有tkinter的可调整大小的可滚动画布 [英] resizeable scrollable canvas with tkinter

查看:99
本文介绍了带有tkinter的可调整大小的可滚动画布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是一个非常简单的gui的代码:

 从Tkinter导入* 

类my_gui (帧):

def __init __(self):
#主tk对象
self.root = Tk()

#初始化帧
Frame .__ init __(self,self.root)

#创建框架(灰色窗口)
self.frame = Frame(self.root,width = 100,height = 100)
self.frame.grid(row = 0,column = 0)

self .__ add_scroll_bars()

self .__ create_canvas()

self .__ add_plot()

def __create_canvas(self):
#在窗口中创建用于绘制
的白色区域#宽度和高度仅为白色区域的可见大小,scrollregion是用户通过滚动
可以看到的区域self.canvas = Canvas(self.frame,bg ='#FFFFFF',width = 300,height = 300,scrollregion =(0,0,500,500))

#使用此命令,窗口将充满画布
self.canvas.pack(side = LEFT,expand = True,fill = BOTH)

#画布的位置和大小用于配置滚动条
self.canvas.config (xscrollcommand = self.hbar.set,yscrollcommand = self.vbar.set)

#向滚动条添加命令以滚动画布
self.hbar.config(command = self。 canvas.xview)
self.vbar.config(command = self.canvas.yview)

def __add_scroll_bars(self):
#添加滚动条
self。 hbar = Scrollbar(self.frame,orient =水平)
self.hbar.pack(边=底部,填充= X)
self.vbar = Scrollbar(self.frame,orient =垂直)
self.vbar.pack(side = RIGHT,fill = Y)

def __add_plot(self):
#创建一个矩形
self.canvas.create_polygon(10, 10、10、150、200、150、200、10,fill = gray,outline = black)

def mainLoop(self):
#此函数启动endlos运行线程t通过gui
self.root.mainloop()

def __quit(self):
#关闭所有
self.root.quit()

def mainLoop(self):
#此函数通过gui
self.root.mainloop()

#初始化gui
my_gui = my_gui()
#执行gui
my_gui.mainLoop()

我有两个问题:



1)我想如果调整gui的大小,那么滚动条将始终位于gui的末端,并调整画布的大小。 / p>

2)如果我调整了GUI和画布的大小,那么画布中的矩形将被调整大小(例如,如果gui和canvas的新大小是旧大小的四倍)



我分别搜索第一个问题和第二个问题的解决方案。



感谢您的帮助。

解决方案

l,以最小的可滚动画布大小获得我想要的东西。但是仍然存在一个错误,当gui变大并且看起来好像无法滚动时,可以单击滚动条的左箭头或上箭头,这样就可以滚动画布了,

 从Tkinter导入* 


类ScrollableFrame(Frame):
def __init __(self,parent,minimal_canvas_size,* args,** kw):
'''
构造函数
'''

框架。 __init __(self,parent,* args,** kw)

self.minimal_canvas_size = minimal_canvas_size

#创建一个垂直滚动条
vscrollbar =滚动条(自身,东方=垂直)
vscrollbar.pack(填充= Y,侧面=右,展开=假)

#创建一个水平滚动条
hscrollbar =滚动条(self,Orient = HORIZONTAL)
hscrollbar.pack(填充= X,侧面=底部,展开=假)

#创建一个画布对象并将滚动条与其关联
self.canvas = Canvas(self,bd = 0,Highlightthickness = 0,yscrollcommand = vscrollbar.set,xscrollcommand = hscrollbar.set)
self.canvas.pack(side = LEFT,fill = BOTH,expand = TRUE)

#将滚动条与画布视图关联
vscrollbar.config(command = self.canvas.yview)
hscrollbar.config(command = self.canvas.xview)


#初始化时将视图设置为0,0

self.canvas.xview_moveto(0)
self。 canvas.yview_moveto(0)

self.canvas.config(scrollregion ='0 0%s%s'%self.minimal_canvas_size)

#创建一个内部框架在画布内部创建

self.interior =内部=框架(self.canvas)
interior_id = self.canvas.create_window(0,0,window = interior,
anchor = NW)

#跟踪对画布和框架宽度的更改并同步它们,
#同时更新滚动条

def _configure_interior(event):
#更新滚动条以匹配内部框架的大小
size =(max(interior.winfo_reqwidth (),self.minimal_canvas_size [0]),max(interior.winfo_reqheight(),self.minimal_canvas_size [1]))
self.canvas.config(scrollregion ='0 0%s%s'%size)
if interior.winfo_reqwidth()!= self.canvas.winfo_width():
#更新画布的宽度以适合内部框架
self.canvas.config(width = interior.winfo_reqwidth( ))
interior.bind('< Configure>',_configure_interior)


class my_gui(Frame):

def __init __(self) :
#主tk对象
self.root = Tk()

#初始化帧
Frame .__ init __(self,self.root)

minimal_canvas_size =(500,500)

#创建框架(灰色窗口)

self.frame = ScrollableFrame(self.root,minimal_canvas_size)
self.frame.pack(fill = BOTH,expand = YES)

self .__ add_plot()

def __add_plot(self):
#创建一个矩形
self.frame.canvas.create_polygon(10,10,10,150,200,150,200,10,fill = gray,轮廓= black)

def mainLoop(self):
#此函数通过gui
self.root.mainloop()
$启动一个运行endlos的线程b $ b def __quit(self):
#关闭所有内容
self.root.quit()


#初始化gui
my_gui = my_gui( )
#执行gui
my_gui.mainLoop()


Here my code for a very simple gui:

from Tkinter import *

class my_gui(Frame):

    def __init__(self):
        # main tk object
        self.root = Tk()

        # init Frame
        Frame.__init__(self, self.root)

        # create frame (gray window)
        self.frame=Frame(self.root,width=100,height=100)
        self.frame.grid(row=0,column=0)

        self.__add_scroll_bars()

        self.__create_canvas()

        self.__add_plot()

    def __create_canvas(self):
        # create white area in the window for plotting
        # width and height are only the visible size of the white area, scrollregion is the area the user can see by scrolling
        self.canvas = Canvas(self.frame,bg='#FFFFFF',width=300,height=300,scrollregion=(0,0,500,500))

        # with this command the window is filled with the canvas
        self.canvas.pack(side=LEFT,expand=True,fill=BOTH)

        # position and size of the canvas is used for configuration of the scroll bars
        self.canvas.config(xscrollcommand=self.hbar.set, yscrollcommand=self.vbar.set)

        # add command to the scroll bars to scroll the canvas
        self.hbar.config(command = self.canvas.xview)
        self.vbar.config(command = self.canvas.yview)

    def __add_scroll_bars(self):
        # add scroll bars
        self.hbar=Scrollbar(self.frame,orient=HORIZONTAL)
        self.hbar.pack(side=BOTTOM,fill=X)
        self.vbar=Scrollbar(self.frame,orient=VERTICAL)
        self.vbar.pack(side=RIGHT,fill=Y)

    def __add_plot(self):
        # create a rectangle
        self.canvas.create_polygon(10, 10, 10, 150, 200, 150, 200, 10,  fill="gray", outline="black")

    def mainLoop(self):
        # This function starts an endlos running thread through the gui
        self.root.mainloop()

    def __quit(self):
        # close everything
        self.root.quit()

    def mainLoop(self):
        # This function starts an endlos running thread through the gui
        self.root.mainloop()

# init gui
my_gui = my_gui()
# execute gui
my_gui.mainLoop()

I have two questions:

1) I want if I resize the gui, that then the scrollbars are always on the Ends of the gui and I resize the canvas.

2) If I resize the GUI and the canvas, then the rectangle in the canvas shall be resized (for example if the new size of gui and canvas is four times the old size, then the new size of rectangle is twize the old size).

I search a solution for the first problem and for the second problem seperately.

Thanks for help.

解决方案

This works very well, to get what I want with the minimal scrollable canvas size. But there is still the bug, when the gui was made larger and when it seems so, that one can not scroll, there is the possibility to click on the left or upper arrow of the scroll bars and so to scroll the canvas, what sould not be possible.

from Tkinter import *


class ScrollableFrame(Frame):
    def __init__(self, parent, minimal_canvas_size, *args, **kw):
        '''
        Constructor
        '''

        Frame.__init__(self, parent, *args, **kw)

        self.minimal_canvas_size = minimal_canvas_size

        # create a vertical scrollbar
        vscrollbar = Scrollbar(self, orient = VERTICAL)
        vscrollbar.pack(fill = Y, side = RIGHT, expand = FALSE)

        # create a horizontal scrollbar
        hscrollbar = Scrollbar(self, orient = HORIZONTAL)
        hscrollbar.pack(fill = X, side = BOTTOM, expand = FALSE)

        #Create a canvas object and associate the scrollbars with it
        self.canvas = Canvas(self, bd = 0, highlightthickness = 0, yscrollcommand = vscrollbar.set, xscrollcommand = hscrollbar.set)
        self.canvas.pack(side = LEFT, fill = BOTH, expand = TRUE)

        #Associate scrollbars with canvas view
        vscrollbar.config(command = self.canvas.yview)
        hscrollbar.config(command = self.canvas.xview)


        # set the view to 0,0 at initialization

        self.canvas.xview_moveto(0)
        self.canvas.yview_moveto(0)

        self.canvas.config(scrollregion='0 0 %s %s' % self.minimal_canvas_size)

        # create an interior frame to be created inside the canvas

        self.interior = interior = Frame(self.canvas)
        interior_id = self.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 = (max(interior.winfo_reqwidth(), self.minimal_canvas_size[0]), max(interior.winfo_reqheight(), self.minimal_canvas_size[1]))
            self.canvas.config(scrollregion='0 0 %s %s' % size)
            if interior.winfo_reqwidth() != self.canvas.winfo_width():
                # update the canvas's width to fit the inner frame
                self.canvas.config(width = interior.winfo_reqwidth())
        interior.bind('<Configure>', _configure_interior)


class my_gui(Frame):

    def __init__(self):
        # main tk object
        self.root = Tk()

        # init Frame
        Frame.__init__(self, self.root)

        minimal_canvas_size = (500, 500)

        # create frame (gray window)

        self.frame = ScrollableFrame(self.root, minimal_canvas_size)
        self.frame.pack(fill=BOTH, expand=YES)

        self.__add_plot()

    def __add_plot(self):
        # create a rectangle
        self.frame.canvas.create_polygon(10, 10, 10, 150, 200, 150, 200, 10,  fill="gray", outline="black")

    def mainLoop(self):
        # This function starts an endlos running thread through the gui
        self.root.mainloop()

    def __quit(self):
        # close everything
        self.root.quit()


# init gui
my_gui = my_gui()
# execute gui
my_gui.mainLoop()

这篇关于带有tkinter的可调整大小的可滚动画布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆