tkinter画布滚动条与网格? [英] tkinter Canvas Scrollbar with Grid?

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

问题描述

Tkinter和Python相对较新。我试图显示下面的图形用户界面,并希望在Frame2中有一个滚动条,一次只显示5x5按钮。看起来像Tkinter框架不支持滚动条,因此添加了一个画布(框架嵌入其中)和父框架'FMas'中的滚动条。但由于某种原因,滚动条会移到屏幕的右端,并且不会进行任何滚动。

不应该画布在Frame2的边缘结束,滚动条靠近它吗?另外,我尝试使用rowspan来增加滚动条的高度以匹配5x5按钮的高度。这也行不通。





CODE (使用Python3.2):

  from tkinter import * 
import tkinter.ttk as ttk

mGui = Tk()

mGui.geometry(630x600)
mGui.configure(background =Gray)

mGui.columnconfigure 0,weight = 1)
mgui.rowconfigure(0,weight = 1)

FMas = Frame(mGui,bg =Gray)
FMas.grid(sticky = (N,E,S,W))

FMas.columnconfigure(0,weight = 1)

L1 =标签(FMas,text =Frame 1 Contents)
L1.grid(row = 0,column = 0,pady = 5,sticky =(N,W))

F1 = Frame(FMas,bg =Green,bd = 2,relief = GROOVE)
F1.grid(row = 1,column = 0,sticky =(N,W))

ChkBox1 = IntVar()
CB1 = Checkbutton (F1,text =StartCheckBox,variable = ChkBox1)
CB1.grid(row = 0,column = 0,padx = 2)

L2 =标签(FMas,text =神父ame 2 Contents)
L2.grid(row = 2,column = 0,pady = 5,sticky =(N,W))

Can1 = Canvas(FMas,bg =黄色)
Can1.grid(row = 3,column = 0,sticky =(N,W))

F2 = Frame(Can1,bg =Blue,bd = 2 ,relief = GROOVE)
F2.grid(row = 0,column = 0,sticky =(N,W))

rows = 10
(1,6):
button =按钮(F2,padx = 7,pady = 7,text =[%d,%d]%(i) ,j))
button.grid(row = i,column = j,sticky ='news')

vsbar =滚动条(FMas,orient =vertical,command = Can1。 yview)
vsbar.grid(row = 3,column = 1)

Can1.configure(yscrollcommand = vsbar.set,scrollregion = Can1.bbox(all))

L3 =标签(FMas,text =Frame 3 Contents)
L3.grid(row = 4,column = 0,pady = 5,sticky =(N,W))

F3 = Frame(FMas,bg =Red,bd = 2,relief = GROOVE)
F3.grid(row = 5,column = 0,sticky =(N,W))

ChkBox2 = IntVar()
CB2 = Checkbutton(F3,text =EndCheckBox,variable = ChkBox2)
CB2.grid(row = 0,column = 0,pad x = 2)

mGui.mainloop()
sys.exit()


你的滚动条的高度与按钮框架的高度不匹配,因为你没有告诉它粘贴南北 .grid(。 ..,sticky ='ns')



然后,您想实现的滚动行为在这里描述:

  import tkinter as tk 

root = tk.Tk()
root.grid_rowconfigure(0,weight = 1)
root.columnconfigure(0,weight = 1)

frame_main = tk.Frame(root,bg =gray)
frame_main.grid(sticky ='news')

label1 = tk.Label(frame_main, text =Label 1,fg =green)
label1.grid(row = 0,column = 0,pady =(5,0),sticky ='nw')

label2 = tk.Label(frame_main,text =Label 2,fg =blue)
label2.grid(row = 1,column = 0,pady =(5,0),sticky ='nw ')

label3 = tk.Label(frame_main,text =Label 3,fg =red)
label3.grid(row = 3,column = 0,pady = 5) ,sticky ='nw')

#为画布创建一个非零行和列权重的框架
frame_canvas = tk.Frame(frame_main)
frame_canvas.grid(行= 2,列= 0,pady =(5,0),sticky ='nw' )
frame_canvas.grid_rowconfigure(0,weight = 1)
frame_canvas.grid_columnconfigure(0,weight = 1)
#将grid_propagate设置为False以允许5乘5按钮调整大小
frame_canvas.grid_propagate(False)

#在该帧中添加画布
canvas = tk.Canvas(frame_canvas,bg =yellow)
canvas.grid(row = 0,column = 0,sticky =news)

#将滚动条链接到画布
vsb = tk.Scrollbar(frame_canvas,orient =vertical,command = canvas。 yview)
vsb.grid(row = 0,column = 1,sticky ='ns')
canvas.configure(yscrollcommand = vsb.set)

#创建一个框架包含按钮
frame_buttons = tk.Frame(canvas,bg =blue)
canvas.create_window((0,0),window = frame_buttons,anchor ='nw')

#将9×5按钮添加到框架
rows = 9
columns = 5
buttons = [[xk(列)中j的tk.Button()]对于我在xrange(行)中]
为范围内的(0,行):
为范围内的j(0,列):
buttons [i] [j] = tk。 Button(frame_buttons,text =(%d,%d%(i + 1,j + 1)))
buttons [i] [j] .grid(row = i,column = j,sticky = 'news')

#更新按钮框架空闲任务让tkinter计算按钮大小
frame_buttons.update_idletasks()

#调整画布框的大小以准确显示5 (按钮[0] [j] .winfo_width()在范围内(0,5)])
first5rows_height = sum([buttons []按钮和滚动条
first5columns_width = sum i)[0] .winfo_height()for i in range(0,5)])
frame_canvas.config(width = first5columns_width + vsb.winfo_width(),
height = first5rows_height)

#设置画布滚动区域
canvas.config(scrollregion = canvas.bbox(all))

#启动GUI
root.mainloop()


Relatively new to Tkinter and Python. So kindly bear with me.

I am trying to display the following GUI and want to have a scrollbar in Frame2 to display only 5x5 buttons at a time. Looks like Tkinter Frames don't support scrollbar and hence added a canvas (within which the frame is embedded) and a scrollbar in the parent frame 'FMas'. But for some reason the scroll bar goes to the right end of the screen and doesn't do any scrolling.

Shouldn't the canvas end at the edge of the Frame2 and the scroll bar be right next to it? Also, I tried rowspan to increase the height of the scrollbar to match the height of 5x5 buttons. That too doesn't work.

CODE (Using Python3.2):

from tkinter import *
import tkinter.ttk as ttk

mGui = Tk()

mGui.geometry("630x600")
mGui.configure(background="Gray")

mGui.columnconfigure(0, weight=1)
mGui.rowconfigure(0, weight=1)

FMas = Frame(mGui, bg="Gray")
FMas.grid(sticky=(N,E,S,W))

FMas.columnconfigure(0, weight=1)

L1 = Label(FMas, text="Frame 1 Contents")
L1.grid(row=0, column=0, pady=5, sticky=(N,W))

F1 = Frame(FMas, bg="Green", bd=2, relief=GROOVE)
F1.grid(row=1, column=0, sticky=(N,W))

ChkBox1=IntVar()
CB1 = Checkbutton(F1, text="StartCheckBox", variable=ChkBox1)
CB1.grid(row=0,column=0,padx=2)

L2 = Label(FMas, text="Frame 2 Contents")
L2.grid(row=2, column=0, pady=5, sticky=(N,W))

Can1 = Canvas(FMas, bg="Yellow")
Can1.grid(row=3, column=0, sticky=(N,W))

F2 = Frame(Can1, bg="Blue", bd=2, relief=GROOVE)
F2.grid(row=0, column=0, sticky=(N,W))

rows = 10
for i in range(1,rows):
    for j in range(1,6):
        button = Button(F2, padx=7, pady=7, text="[%d,%d]" % (i,j))
        button.grid(row=i, column=j, sticky='news')

vsbar = Scrollbar(FMas, orient="vertical", command=Can1.yview)
vsbar.grid(row=3, column=1)

Can1.configure(yscrollcommand=vsbar.set, scrollregion=Can1.bbox("all"))

L3 = Label(FMas, text="Frame 3 Contents")
L3.grid(row=4, column=0, pady=5, sticky=(N,W))

F3 = Frame(FMas, bg="Red", bd=2, relief=GROOVE)
F3.grid(row=5, column=0, sticky=(N,W))

ChkBox2=IntVar()
CB2 = Checkbutton(F3, text="EndCheckBox", variable=ChkBox2)
CB2.grid(row=0,column=0,padx=2)

mGui.mainloop()
sys.exit()

解决方案

The height of your scrollbar didn't match the buttons frame height because you did't tell it to stick North and South .grid(..., sticky='ns')

Then, the scrolling behavior you want to achieve is described here: Adding a Scrollbar to a group of widgets

See also @martineau's answer for a more general object-oriented solution with 2D scrolling (horizontal & vertical)

import tkinter as tk

root = tk.Tk()
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)

frame_main = tk.Frame(root, bg="gray")
frame_main.grid(sticky='news')

label1 = tk.Label(frame_main, text="Label 1", fg="green")
label1.grid(row=0, column=0, pady=(5, 0), sticky='nw')

label2 = tk.Label(frame_main, text="Label 2", fg="blue")
label2.grid(row=1, column=0, pady=(5, 0), sticky='nw')

label3 = tk.Label(frame_main, text="Label 3", fg="red")
label3.grid(row=3, column=0, pady=5, sticky='nw')

# Create a frame for the canvas with non-zero row&column weights
frame_canvas = tk.Frame(frame_main)
frame_canvas.grid(row=2, column=0, pady=(5, 0), sticky='nw')
frame_canvas.grid_rowconfigure(0, weight=1)
frame_canvas.grid_columnconfigure(0, weight=1)
# Set grid_propagate to False to allow 5-by-5 buttons resizing later
frame_canvas.grid_propagate(False)

# Add a canvas in that frame
canvas = tk.Canvas(frame_canvas, bg="yellow")
canvas.grid(row=0, column=0, sticky="news")

# Link a scrollbar to the canvas
vsb = tk.Scrollbar(frame_canvas, orient="vertical", command=canvas.yview)
vsb.grid(row=0, column=1, sticky='ns')
canvas.configure(yscrollcommand=vsb.set)

# Create a frame to contain the buttons
frame_buttons = tk.Frame(canvas, bg="blue")
canvas.create_window((0, 0), window=frame_buttons, anchor='nw')

# Add 9-by-5 buttons to the frame
rows = 9
columns = 5
buttons = [[tk.Button() for j in xrange(columns)] for i in xrange(rows)]
for i in range(0, rows):
    for j in range(0, columns):
        buttons[i][j] = tk.Button(frame_buttons, text=("%d,%d" % (i+1, j+1)))
        buttons[i][j].grid(row=i, column=j, sticky='news')

# Update buttons frames idle tasks to let tkinter calculate buttons sizes
frame_buttons.update_idletasks()

# Resize the canvas frame to show exactly 5-by-5 buttons and the scrollbar
first5columns_width = sum([buttons[0][j].winfo_width() for j in range(0, 5)])
first5rows_height = sum([buttons[i][0].winfo_height() for i in range(0, 5)])
frame_canvas.config(width=first5columns_width + vsb.winfo_width(),
                    height=first5rows_height)

# Set the canvas scrolling region
canvas.config(scrollregion=canvas.bbox("all"))

# Launch the GUI
root.mainloop()

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

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