[英]How to add 2 scrollbars with tkinter in python 3.4?
I have the following code: 我有以下代码:
from win32com.client import Dispatch
from tkinter import *
from tkinter import ttk
import tkinter
class applicazione:
def __init__(self, root):
self.root = root
self.root.title('Controllo dati per fatturazione elettronica - Manticle - Smith & Nephew Italia')
ttk.Frame(self.root, width=300, height=250).pack()
#### label list
self.titoli = list()
self.titoli_BFT = ["Num_Doc", "Cod_Art", "Unita Misura", "Tot_Prod", "Quant_Prod", "Perc_IVA_Prod", "Tot_IVA_Prod",
"Linea_Prod", "Sconto", "Perc_Sconto", "Tipo_Sconto", "Cod_Art2", "Desc_Art"]
self.titoli_HFT = ["Dest_Cod_FIS_P_Iva", "Cod_Cli", "Dest_RagSoc1", "Dest_RagSoc2",
"Dest_Indirizzo", "Dest_CAP", "Dest_Localita", "Dest_Provincia", "Cli_Cod_Fis_P_Iva",
"Cod_Dest", "Cli_RagSoc1", "Cli_RagSoc2", "Cli_Indirizzo", "Cli_CAP",
"Cli_Localita", "Cli_Provincia", "Tipo_Doc", "pre_Num_Doc", "Num_Doc",
"Data_Doc", "Vs_Rif", "Data_Rif", "Blank", "Blank2", "CPT", "Scad_Pagamento",
"Descr", "Num_Ord", "Tot_Imp", "Tot_IVA", "Tot_Doc", "Nazione", "IPA", "Reg_Fiscale"]
self.titoli_IVA = ["Num_Doc_TMP", "Num_Doc", "Imponibile", "IVA, Tot", "Perc_IVA"]
self.titoli_RIF_DOC = [ "Num_Doc_TMP", "Num_Doc", "Rif_Doc" ]
self.titoli_RIF_DOC_BFT = ["Num_Doc_TMP", "Num_Doc", "Cod_Art", "NOTE" ]
self.titoli_anomalieBFT = ["ordine", "anomalia"]
self.titoli_anomalieHFT = ["ordine", "anomalia"]
self.inizializza_widgets()
self.lettura()
def inizializza_widgets(self):
#label
self.lblins=tkinter.Label(self.root, text="Controllo dati per fatturazione elettronica", font=("Helvetica", 12))
self.lblins.place(x=10, y=10
for i in range (0,len(self.titoli_HFT)):
j = 80*i
self.lblnome=tkinter.Label(self.root, text= self.titoli_HFT[i], font=("Helvetica", 8))
self.lblnome.place(x=85+j, y=50)
#buttons
ttk.Button(self.root, , text='Inserisci', width='10').place(x=645, y=590)
#pulsante lettura
ttk.Button(self.root, text='Modifica', width='10').place(x=725, y=590)
ttk.Button(self.root, text='Indietro', width='10').place(x=805, y=590)
ttk.Button(self.root, text='Avanti', width='10').place(x=885, y=590)
def onFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def lettura(self):
xl= Dispatch("Excel.Application")
xl.Visible = True
self.checkb_intvar = list() #contiene una lista di 1 o 0 associati alle checkbox nella lista quadratini
self.quadratiniB = l = [None] * (13 * len(self.titoli_BFT) )
self.quadratiniH = l = [None] * (13 * len(self.titoli_HFT) )
wbH = xl.Workbooks.Open(r'C:\Users\\Marco\\LAVORO\\Smith&Nephew\\appRonca\\fonte\\HFT_SAP_2.csv')
print("wbH")
wsH=wbH.WorkSheets(1) # get a reference to the first sheet
cont = 0
MAX = 3 #13 lunghezza visibile senza barra navigatrice del numero di righe nella finestra 13
cont = 0
for i in range(0, MAX):
for j in range(0,len(self.titoli_HFT)):
print("for for")
cont = cont + 1
print("i")
print(i)
print("j")
print(j)
print(" The {} set is often represented as {{0}} ".format("empty"))
#### indexes for DI excel cells management
k = 80*j #i con j
l = 40*i #k con l
contvalueX = i + 1 #con zero da errore allora +1
contvalueY = j + 1 #con zero da errore allora +1
self.txt1 = tkinter.Text(self.root, width='10', height='1')
#Reading excel cells file
if (wsH.Cells(contvalueX, contvalueY ).Value != None):
self.txt1.insert('1.0', wsH.Cells(contvalueX, contvalueY ).Value)#ws.Cells(1,i).Value
self.txt1.tag_add("start", "1.0", "1.13")
if (contvalueY == 1 ):
self.txt1.tag_config("start", background="white", foreground="red")
#self.txt1.tag_configure("red", foreground="red")
#self.txt1.highlight_pattern("word", "red")
#self.txt1 = tkinter.Text(self.root, width='10', height='1', text = ws.Cells(1,i).Value)
self.txt1.place(x=85+k, y=80+l) #5 + 80
print("if")
else: #None case
print("else")
self.txt1.insert('1.0', "")
self.txt1.place(x=85+k, y=80+l)
if (contvalueY == 1 ):
self.txt1.tag_config("start", background="white", foreground="red")
wbH.Close()
xl.Quit()
if __name__ == '__main__':
root = tkinter.Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry("%dx%d+0+0" % (w, h))
applicazione(root)
root.mainloop()
The application runned: 该应用程序运行:
I read data from an excel file (lettura function) but i would like to add an horizontal and a vertical scrollbar i read first of all this: 我从excel文件(lettura函数)中读取数据,但我想添加一个水平和垂直滚动条,我首先要阅读以下内容:
Adding a scrollbar to a group of widgets in Tkinter 在Tkinter中向一组小部件添加滚动条
but use "grid" that i do not use and i'm not able to associate my double "for" "Text" to the vertical scroll bar (Lettura function) 但是使用我不使用的“网格”,并且我无法将我的双“ for”“文本”关联到垂直滚动条(Lettura函数)
The following code is edited with the scrollbar but does not work: 以下代码是使用滚动条编辑的,但无效:
import tkinter as tk
from win32com.client import Dispatch
from tkinter import *
#from tkinter import ttk
import tkinter
class Example(tk.Frame):
def __init__(self, root):
tk.Frame.__init__(self, root)
root.title('Controllo dati per fatturazione elettronica - Manticle - Smith & Nephew Italia')
#tk.Frame(root, width=100, height=450).pack()
self.canvas = tk.Canvas(root, borderwidth=0, background="#C0C0C0")
self.frame = tk.Frame(self.canvas, background="#ffffff")
self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.vsb.set)
self.vsb.pack(side="right", fill="y")
self.canvas.pack(side="left", fill="both", expand=True)
self.canvas.create_window((4,4), window=self.frame, anchor="nw",
tags="self.frame")
self.frame.bind("<Configure>", self.onFrameConfigure)
self.titoli_BFT = ["Num_Doc", "Cod_Art", "Unita Misura", "Tot_Prod", "Quant_Prod", "Perc_IVA_Prod", "Tot_IVA_Prod",
"Linea_Prod", "Sconto", "Perc_Sconto", "Tipo_Sconto", "Cod_Art2", "Desc_Art"]
self.titoli_HFT = ["Dest_Cod_FIS_P_Iva", "Cod_Cli", "Dest_RagSoc1", "Dest_RagSoc2",
"Dest_Indirizzo", "Dest_CAP", "Dest_Localita", "Dest_Provincia", "Cli_Cod_Fis_P_Iva",
"Cod_Dest", "Cli_RagSoc1", "Cli_RagSoc2", "Cli_Indirizzo", "Cli_CAP",
"Cli_Localita", "Cli_Provincia", "Tipo_Doc", "pre_Num_Doc", "Num_Doc",
"Data_Doc", "Vs_Rif", "Data_Rif", "Blank", "Blank2", "CPT", "Scad_Pagamento",
"Descr", "Num_Ord", "Tot_Imp", "Tot_IVA", "Tot_Doc", "Nazione", "IPA", "Reg_Fiscale"]
#self.inizializza_widgets()
self.populate()
self.lettura()
def inizializza_widgets(self):
#label title
self.lblins=tk.Label(root, text="Controllo dati per fatturazione elettronica", font=("Helvetica", 12))
self.lblins.place(x=10, y=10)
for i in range (0,len(self.titoli_HFT)):
j = 80*i
self.lblnome=tk.Label(root, text= self.titoli_HFT[i], font=("Helvetica", 8))
self.lblnome.place(x=85+j, y=50)
#965 560
tk.Button(root, text='Inserisci', width='10').place(x=645, y=590)
#pulsante lettura
tk.Button(root, text='Modifica', width='10').place(x=725, y=590)
tk.Button(root, text='Indietro', width='10').place(x=805, y=590)
tk.Button(root, text='Avanti', width='10').place(x=885, y=590)
def lettura(self):
xl= Dispatch("Excel.Application")
xl.Visible = True
wbH = xl.Workbooks.Open(r'C:\Users\\Marco\\LAVORO\\Smith&Nephew\\appRonca\\fonte\\HFT_SAP_2.csv')
print("wbH")
wsH=wbH.WorkSheets(1) # get a reference to the first sheet
cont = 0
MAX = 9 #13 lunghezza visibile senza barra navigatrice del numero di righe nella finestra 13
cont = 0
for i in range(0, MAX):
for j in range(0,len(self.titoli_HFT)):
print("for for")
cont = cont + 1
print("cont")
print(cont)
#### INDEXES
k = 80*j #i con j
l = 40*i #k con l
contvalueX = i + 1 #con zero da errore allora +1
contvalueY = j + 1 #con zero da errore allora +1
self.txt1 = tk.Text(root, width='10', height='1')
#Lettura celle del file HFT
if (wsH.Cells(contvalueX, contvalueY ).Value != None):
self.txt1.insert('1.0', wsH.Cells(contvalueX, contvalueY ).Value)#ws.Cells(1,i).Value
self.txt1.tag_add("start", "1.0", "1.13")
if (contvalueY == 1 ):
self.txt1.tag_config("start", background="white", foreground="red")
self.txt1.place(x=85+k, y=80+l) #5 + 80
print("if")
else: #None case
print("else")
self.txt1.insert('1.0', "")
self.txt1.place(x=85+k, y=80+l)
if (contvalueY == 1 ): #### qui si richiama la funziona regole con tutte le regole
self.txt1.tag_config("start", background="white", foreground="red")
wbH.Close()
xl.Quit()
def onFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
if __name__ == "__main__":
root=tk.Tk()
Example(root).pack(side="top", fill="both", expand=True)
root.mainloop()
and this: How to add a scrollbar to a window with tkinter? 这: 如何使用tkinter将滚动条添加到窗口? that is not organise like a class.
那不是一个班级组织的。
how can i implement the 2 scrollbars? 如何实现2个滚动条?
UPDATE 更新
new version: 新版本:
from win32com.client import Dispatch
from tkinter import *
from tkinter import ttk
import tkinter
class applicazione:
def __init__(self, root):
self.root = root
# Top-level frame
self.frame = ttk.Frame(self.root, relief="sunken")
# Canvas creation with double scrollbar
hscrollbar = ttk.Scrollbar(self.frame, orient = tkinter.HORIZONTAL)
vscrollbar = ttk.Scrollbar(self.frame, orient = tkinter.VERTICAL)
self.canvas = tkinter.Canvas(self.frame, bd=0, highlightthickness=0, yscrollcommand = vscrollbar.set, xscrollcommand = hscrollbar.set)
vscrollbar.config(command = self.canvas.yview)
hscrollbar.config(command = self.canvas.xview)
# Add controls here
self.subframe = ttk.Frame(self.canvas)
#Packing everything
self.subframe.pack(padx = 15, pady = 15, fill = tkinter.BOTH, expand = tkinter.TRUE)
hscrollbar.pack( fill=tkinter.X, side=tkinter.BOTTOM, expand=tkinter.FALSE)
vscrollbar.pack( fill=tkinter.Y, side=tkinter.RIGHT, expand=tkinter.FALSE)
self.canvas.pack(side = tkinter.LEFT, padx = 5, pady = 5, fill = tkinter.BOTH, expand= tkinter.TRUE)
self.frame.pack( padx = 5, pady = 5, expand = True, fill = tkinter.BOTH)
self.canvas.create_window(0,0, window = self.subframe)
self.root.update_idletasks() # update geometry
self.canvas.config(scrollregion = self.canvas.bbox("all"))
self.canvas.xview_moveto(0)
self.canvas.yview_moveto(0)
self.root.title('Controllo dati per fatturazione elettronica - Manticle - Smith & Nephew Italia')
ttk.Frame(self.root, width=300, height=250).pack()
#### Titles
self.titoli_HFT = ["Dest_Cod_FIS_P_Iva", "Cod_Cli", "Dest_RagSoc1", "Dest_RagSoc2",
"Dest_Indirizzo", "Dest_CAP", "Dest_Localita", "Dest_Provincia", "Cli_Cod_Fis_P_Iva",
"Cod_Dest", "Cli_RagSoc1", "Cli_RagSoc2", "Cli_Indirizzo", "Cli_CAP",
"Cli_Localita", "Cli_Provincia", "Tipo_Doc", "pre_Num_Doc", "Num_Doc",
"Data_Doc", "Vs_Rif", "Data_Rif", "Blank", "Blank2", "CPT", "Scad_Pagamento",
"Descr", "Num_Ord", "Tot_Imp", "Tot_IVA", "Tot_Doc", "Nazione", "IPA", "Reg_Fiscale"]
self.inizializza_widgets()
def inizializza_widgets(self):
self.lblins=tkinter.Label(self.root, text="Controllo dati per fatturazione elettronica", font=("Helvetica", 12))
self.lblins.place(x=10, y=10)
for i in range (0,len(self.titoli_HFT)):
j = 80*i
self.lblnome=tkinter.Label(self.root, text= self.titoli_HFT[i], font=("Helvetica", 8))
self.lblnome.place(x=85+j, y=50)
ttk.Button(self.root, text='Inserisci', width='10').place(x=645, y=590)
ttk.Button(self.root, text='Modifica', width='10').place(x=725, y=590)
ttk.Button(self.root, text='Indietro', width='10').place(x=805, y=590)
ttk.Button(self.root, text='Avanti', width='10').place(x=885, y=590)
if __name__ == '__main__':
root = tkinter.Tk()
root.title( "Double scrollbar with tkinter" )
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry("%dx%d+0+0" % (w, h))
applicazione(root)
root.mainloop()
I've also struggled with creating a double scrollbar window. 我也一直在努力创建一个双滚动条窗口。 Here is an implementation using
pack
layout manager (you should be able to tailor it for a grid
layout) : 这是一个使用
pack
布局管理器的实现(您应该能够为grid
布局定制它):
import tkinter as tk
from tkinter import ttk
# Top-level frame
root = tk.Tk()
root.title( "Double scrollbar with tkinter" )
root.minsize(width = 600, height = 600)
frame = ttk.Frame(root, relief="sunken")
# Canvas creation with double scrollbar
hscrollbar = ttk.Scrollbar(frame, orient = tk.HORIZONTAL)
vscrollbar = ttk.Scrollbar(frame, orient = tk.VERTICAL)
sizegrip = ttk.Sizegrip(frame)
canvas = tk.Canvas(frame, bd=0, highlightthickness=0, yscrollcommand = vscrollbar.set, xscrollcommand = hscrollbar.set)
vscrollbar.config(command = canvas.yview)
hscrollbar.config(command = canvas.xview)
# Add controls here
subframe = ttk.Frame(canvas)
#Packing everything
subframe.pack(padx = 15, pady = 15, fill = tk.BOTH, expand = tk.TRUE)
hscrollbar.pack( fill=tk.X, side=tk.BOTTOM, expand=tk.FALSE)
vscrollbar.pack( fill=tk.Y, side=tk.RIGHT, expand=tk.FALSE)
sizegrip.pack(in_ = hscrollbar, side = tk.BOTTOM, anchor = "se")
canvas.pack(side = tk.LEFT, padx = 5, pady = 5, fill = tk.BOTH, expand= tk.TRUE)
frame.pack( padx = 5, pady = 5, expand = True, fill = tk.BOTH)
canvas.create_window(0,0, window = subframe)
root.update_idletasks() # update geometry
canvas.config(scrollregion = canvas.bbox("all"))
canvas.xview_moveto(0)
canvas.yview_moveto(0)
# launch the GUI
root.mainloop()
(Tested with Python 3.4). (使用Python 3.4测试)。
It's not perfect, since it lacks the small block on the bottom right corner. 这不是完美的,因为它在右下角缺少小块。
UPDATE 1 : Added Sizegrip to get the bottom right resizing corner 更新1:添加了Sizegrip,以获得右下角的调整大小角
UPDATE 2 : Added working solution to OP's updated code 更新2:在OP的更新代码中添加了工作解决方案
from win32com.client import Dispatch
from tkinter import *
from tkinter import ttk
import tkinter
class applicazione(object):
def __init__(self, root):
self.root = root
# Top-level frame
self.root.title('Controllo dati per fatturazione elettronica - Manticle - Smith & Nephew Italia')
self.frame = ttk.Frame(self.root, width=300, height=250)
# Canvas creation with double scrollbar
hscrollbar = ttk.Scrollbar(self.frame, orient = tkinter.HORIZONTAL)
vscrollbar = ttk.Scrollbar(self.frame, orient = tkinter.VERTICAL)
sizegrip = ttk.Sizegrip(self.frame)
self.canvas = tkinter.Canvas(self.frame, bd=0, highlightthickness=0, yscrollcommand = vscrollbar.set, xscrollcommand = hscrollbar.set)
vscrollbar.config(command = self.canvas.yview)
hscrollbar.config(command = self.canvas.xview)
# Add controls here
self.subframe = ttk.Frame(self.canvas)
#### Titles
self.titoli_HFT = ["Dest_Cod_FIS_P_Iva", "Cod_Cli", "Dest_RagSoc1", "Dest_RagSoc2",
"Dest_Indirizzo", "Dest_CAP", "Dest_Localita", "Dest_Provincia", "Cli_Cod_Fis_P_Iva",
"Cod_Dest", "Cli_RagSoc1", "Cli_RagSoc2", "Cli_Indirizzo", "Cli_CAP",
"Cli_Localita", "Cli_Provincia", "Tipo_Doc", "pre_Num_Doc", "Num_Doc",
"Data_Doc", "Vs_Rif", "Data_Rif", "Blank", "Blank2", "CPT", "Scad_Pagamento",
"Descr", "Num_Ord", "Tot_Imp", "Tot_IVA", "Tot_Doc", "Nazione", "IPA", "Reg_Fiscale"]
self.inizializza_widgets()
#Packing everything
self.subframe.pack(fill = tkinter.BOTH, expand = tkinter.TRUE)
hscrollbar.pack( fill=tkinter.X, side=tkinter.BOTTOM, expand=tkinter.FALSE)
vscrollbar.pack( fill=tkinter.Y, side=tkinter.RIGHT, expand=tkinter.FALSE)
sizegrip.pack(in_= hscrollbar, side = BOTTOM, anchor = "se")
self.canvas.pack(side = tkinter.LEFT, padx = 5, pady = 5, fill = tkinter.BOTH, expand= tkinter.TRUE)
self.frame.pack( padx = 5, pady = 5, expand = True, fill = tkinter.BOTH)
self.canvas.create_window(0,0, window = self.subframe)
self.root.update_idletasks() # update geometry
self.canvas.config(scrollregion = self.canvas.bbox("all"))
self.canvas.xview_moveto(0)
self.canvas.yview_moveto(0)
def inizializza_widgets(self):
self.LabelFrame = ttk.Frame(self.subframe)
self.lblins = tkinter.Label(self.LabelFrame, text="Controllo dati per fatturazione elettronica", font=("Helvetica", 12))
self.lblins.pack()
for i in range (0,len(self.titoli_HFT)):
j = 80*i
self.lblnome=tkinter.Label(self.LabelFrame, text= self.titoli_HFT[i], font=("Helvetica", 8))
self.lblnome.pack(side = LEFT)#place(x=85+j, y=50)
self.ContentFrame = ttk.Frame(self.subframe, width = 600, height = 600)
self.ButtonsFrame = ttk.Frame(self.subframe)
ttk.Frame(self.ButtonsFrame).pack(side=LEFT, fill = X, expand=TRUE)
ttk.Button(self.ButtonsFrame, text='Inserisci', width='10').pack(side = LEFT)
ttk.Button(self.ButtonsFrame, text='Modifica', width='10').pack(side = LEFT)
ttk.Button(self.ButtonsFrame, text='Indietro', width='10').pack(side = LEFT)
ttk.Button(self.ButtonsFrame, text='Avanti', width='10').pack(side = LEFT)
ttk.Frame(self.ButtonsFrame).pack(side=RIGHT, fill = X, expand=TRUE)
self.LabelFrame.pack(side = TOP, fill = X, expand=TRUE)
self.ContentFrame.pack(fill = BOTH, expand = TRUE)
self.ButtonsFrame.pack(side = BOTTOM, fill = X, expand = TRUE)
if __name__ == '__main__':
root = tkinter.Tk()
root.title( "Double scrollbar with tkinter" )
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry("%dx%d+0+0" % (0.99*w, 0.9*h))
applicazione(root)
root.mainloop()
Just to expand on the answer by @georgesl and demonstrate the use of the ttk sizegrip and also to show that grid
works nicely for this kind of task, here is a short example showing a text widget with 2 scrollbars and the sizegrip in the corner. 只是为了扩展@georgesl的答案并演示ttk sizegrip的用法,并显示
grid
可以很好地完成此类任务,这是一个简短的示例,其中显示了一个带有2个滚动条和在角落的sizegrip的文本小部件。
# Demonstrate text widget with two scrollbars and the sizegrip.
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
text = tk.Text(root)
vs = ttk.Scrollbar(root, orient="vertical")
hs = ttk.Scrollbar(root, orient="horizontal")
sizegrip = ttk.Sizegrip(root)
# hook up the scrollbars to the text widget
text.configure(yscrollcommand=vs.set, xscrollcommand=hs.set, wrap="none")
vs.configure(command=text.yview)
hs.configure(command=text.xview)
# grid everything on-screen
text.grid(row=0,column=0,sticky="news")
vs.grid(row=0,column=1,sticky="ns")
hs.grid(row=1,column=0,sticky="news")
sizegrip.grid(row=1,column=1,sticky="news")
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
def fill():
for n in range(30):
text.insert("end", 'hello ' * 20, "", "\n")
root.after(20, fill)
root.mainloop()
The process to add both a horizontal and vertical scrollbar to a collection of widgets is precisely the same as the solution provided in this answer: https://stackoverflow.com/a/3092341/7432 . 将水平和垂直滚动条添加到小部件集合的过程与此答案中提供的解决方案完全相同: https : //stackoverflow.com/a/3092341/7432 。 That answer shows only a vertical scrollbar, but adding a horizontal one is just a matter of a couple lines of code.
该答案仅显示了一个垂直滚动条,但是添加水平滚动条仅需几行代码。
The solution is very straight-forward: 解决方案非常简单:
create_window
method of the canvas create_window
方法将框架添加到画布 scrollregion
attribute of the canvas to be big enough to incude the entire frame that was added scrollregion
属性设置为足够大,以包括添加的整个框架
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.