动态创建小部件 python tkinter 并在 canvas 中添加滚动条
create dynamically widgets python tkinter and adding scroll bar in canvas
我是 Python 和 Whosebug 的新手。
我正在尝试从输入的第一列 CSV 文件中自动创建复选框小部件。我怎样才能让滚动条在正确的位置。下图输入CSV文件前,右边有滚动条
enter image description here
下图输入CSV文件后,checkbox widgets不能滚动
enter image description here
代码使用 python 3.5
import tkinter as tk
from tkinter import ttk
import start
from tkinter.filedialog import askopenfilename
import numpy as np
import pandas as pd
LARGE_FONT=("Verdana", 12)
class MainPage(tk.Frame):
"""docstring for MainPage"""
def __init__(self, parent,controller):
tk.Frame.__init__(self,parent)
self.controller = controller
self.getColumn = []
self.createWidgets()
def createWidgets(self):
self.createPanel()
def createPanel(self):
nb = ttk.Notebook(self)
nb.grid(row=1,column=0,columnspan=50,rowspan=49,sticky="NEWS")
self.createMainPageTab(nb)
self.createClassifyTab(nb)
def createMainPageTab(self,nb):
self.featureSelection = tk.IntVar()
page1 = ttk.Frame(nb)
nb.add(page1,text="Preprocessing")
selectFileFrame = tk.LabelFrame(page1,text = "Select File")
selectFileFrame.grid(row=0,column=0,sticky="W",padx=5,pady=5,ipady=5,columnspan=10)
selectRoleFrame = tk.LabelFrame(page1,text = "select Role")
selectRoleFrame.grid(row=1,column=0,sticky="W",padx=5,pady=5,ipady=5,columnspan=1,rowspan=1)
text = tk.Label(selectFileFrame,text="Select The File")
text.grid(row=0,column=0, sticky="E")
textSelectFile = tk.Text(selectFileFrame,width = 20, height = 1)
textSelectFile.grid(row=0,column=1,sticky="WE",pady=3,padx=5)
buttonSelectFile = tk.Button(selectFileFrame,text="browse...",command=lambda : self.load_file(textSelectFile,frameCheckBox))
buttonSelectFile.grid(row=0,column=2,sticky="w")
checkButtonFeatureSelection = tk.Checkbutton(selectFileFrame, text= "Feature Selection",variable = self.featureSelection)
checkButtonFeatureSelection.grid(row=1,column=0,sticky="w")
buttonCek = tk.Button(selectFileFrame, text='Show', command= lambda : self.var_states())
buttonCek.grid(row=2,column=0,sticky="W")
#create canvas for scroll bar
canvasScroll = tk.Canvas(selectRoleFrame,bg="Yellow")
canvasScroll.grid(row=0,column=0)
vBar = tk.Scrollbar(selectRoleFrame,orient="vertical",command=canvasScroll.yview)
vBar.grid(row=0,column=1, sticky="ns")
canvasScroll.configure(yscrollcommand=vBar.set)
frameCheckBox = tk.Frame(canvasScroll,bg="blue",bd=2,relief=tk.GROOVE)
canvasScroll.create_window((0,0), window=frameCheckBox,anchor="nw")
frameCheckBox.bind("<Configure>",self.resize(canvasScroll))
def resize(self,canvasScroll):
canvasScroll.configure(scrollregion=canvasScroll.bbox("all"),width=235,height=90)
def readingCsv(self,fname):
readCsv = pd.read_csv(fname)
return readCsv
#event input csv file
def load_file(self,textSelectFile,frameCheckBox):
fname = askopenfilename(filetypes=(("*.csv","Template files"),
("HTML files", "*.html;*.htm"),
("All files", "*.*") ))
print(fname)
mlabel = tk.Label(self,text="%s" % fname)
mlabel.grid(row=0,column=3)
# getText=self.textSelectFile.get()
textSelectFile.configure(state=tk.NORMAL)
textSelectFile.delete(1.0,tk.END)
textSelectFile.insert(tk.END,fname)
textSelectFile.configure(state=tk.DISABLED)
read = self.readingCsv(fname)
self.getColumn = self.getColumnFromCsv(read)
#create checkbox
if self.getColumn:
for Column in self.getColumn:
v = tk.StringVar()
l = tk.Checkbutton(frameCheckBox,text=Column,variable=v)
l.grid(sticky="w")
def getColumnFromCsv(self,readCsv):
numeric_variables = list(readCsv.dtypes[readCsv.dtypes != "object"].index)
return numeric_variables
def var_states(self):
alabel = tk.Label(self,text="%s" % self.featureSelection.get())
alabel.grid(row=3,column=0)
print("tes : %d" %(self.featureSelection.get()))
def feature_selection(self,chcekFeatureSelection):
if self.featureSelection.get() == 1:
pass
def createClassifyTab(self,nb):
page2 = ttk.Frame(nb)
nb.add(page2,text="Classify")
你有
frameCheckBox.bind("<Configure>",self.resize(canvasScroll))
这意味着
result = self.resize(canvasScroll)
frameCheckBox.bind("<Configure>", result)
所以你没有分配函数但是你执行了resize
并分配了它的结果。
但是resize
returnsNone
所以你终于得到了
frameCheckBox.bind("<Configure>", None)
bind()
(类似于 command=
)需要回调——这意味着没有 ()
和参数的函数名——像这样
frameCheckBox.bind("<Configure>", self.resize)
因为你想发送额外的参数(并跳过 event
默认情况下由 bind
发送)你必须使用 lambda
frameCheckBox.bind("<Configure>", lambda event: self.resize(canvasScroll))
我是 Python 和 Whosebug 的新手。 我正在尝试从输入的第一列 CSV 文件中自动创建复选框小部件。我怎样才能让滚动条在正确的位置。下图输入CSV文件前,右边有滚动条
enter image description here
下图输入CSV文件后,checkbox widgets不能滚动
enter image description here
代码使用 python 3.5
import tkinter as tk
from tkinter import ttk
import start
from tkinter.filedialog import askopenfilename
import numpy as np
import pandas as pd
LARGE_FONT=("Verdana", 12)
class MainPage(tk.Frame):
"""docstring for MainPage"""
def __init__(self, parent,controller):
tk.Frame.__init__(self,parent)
self.controller = controller
self.getColumn = []
self.createWidgets()
def createWidgets(self):
self.createPanel()
def createPanel(self):
nb = ttk.Notebook(self)
nb.grid(row=1,column=0,columnspan=50,rowspan=49,sticky="NEWS")
self.createMainPageTab(nb)
self.createClassifyTab(nb)
def createMainPageTab(self,nb):
self.featureSelection = tk.IntVar()
page1 = ttk.Frame(nb)
nb.add(page1,text="Preprocessing")
selectFileFrame = tk.LabelFrame(page1,text = "Select File")
selectFileFrame.grid(row=0,column=0,sticky="W",padx=5,pady=5,ipady=5,columnspan=10)
selectRoleFrame = tk.LabelFrame(page1,text = "select Role")
selectRoleFrame.grid(row=1,column=0,sticky="W",padx=5,pady=5,ipady=5,columnspan=1,rowspan=1)
text = tk.Label(selectFileFrame,text="Select The File")
text.grid(row=0,column=0, sticky="E")
textSelectFile = tk.Text(selectFileFrame,width = 20, height = 1)
textSelectFile.grid(row=0,column=1,sticky="WE",pady=3,padx=5)
buttonSelectFile = tk.Button(selectFileFrame,text="browse...",command=lambda : self.load_file(textSelectFile,frameCheckBox))
buttonSelectFile.grid(row=0,column=2,sticky="w")
checkButtonFeatureSelection = tk.Checkbutton(selectFileFrame, text= "Feature Selection",variable = self.featureSelection)
checkButtonFeatureSelection.grid(row=1,column=0,sticky="w")
buttonCek = tk.Button(selectFileFrame, text='Show', command= lambda : self.var_states())
buttonCek.grid(row=2,column=0,sticky="W")
#create canvas for scroll bar
canvasScroll = tk.Canvas(selectRoleFrame,bg="Yellow")
canvasScroll.grid(row=0,column=0)
vBar = tk.Scrollbar(selectRoleFrame,orient="vertical",command=canvasScroll.yview)
vBar.grid(row=0,column=1, sticky="ns")
canvasScroll.configure(yscrollcommand=vBar.set)
frameCheckBox = tk.Frame(canvasScroll,bg="blue",bd=2,relief=tk.GROOVE)
canvasScroll.create_window((0,0), window=frameCheckBox,anchor="nw")
frameCheckBox.bind("<Configure>",self.resize(canvasScroll))
def resize(self,canvasScroll):
canvasScroll.configure(scrollregion=canvasScroll.bbox("all"),width=235,height=90)
def readingCsv(self,fname):
readCsv = pd.read_csv(fname)
return readCsv
#event input csv file
def load_file(self,textSelectFile,frameCheckBox):
fname = askopenfilename(filetypes=(("*.csv","Template files"),
("HTML files", "*.html;*.htm"),
("All files", "*.*") ))
print(fname)
mlabel = tk.Label(self,text="%s" % fname)
mlabel.grid(row=0,column=3)
# getText=self.textSelectFile.get()
textSelectFile.configure(state=tk.NORMAL)
textSelectFile.delete(1.0,tk.END)
textSelectFile.insert(tk.END,fname)
textSelectFile.configure(state=tk.DISABLED)
read = self.readingCsv(fname)
self.getColumn = self.getColumnFromCsv(read)
#create checkbox
if self.getColumn:
for Column in self.getColumn:
v = tk.StringVar()
l = tk.Checkbutton(frameCheckBox,text=Column,variable=v)
l.grid(sticky="w")
def getColumnFromCsv(self,readCsv):
numeric_variables = list(readCsv.dtypes[readCsv.dtypes != "object"].index)
return numeric_variables
def var_states(self):
alabel = tk.Label(self,text="%s" % self.featureSelection.get())
alabel.grid(row=3,column=0)
print("tes : %d" %(self.featureSelection.get()))
def feature_selection(self,chcekFeatureSelection):
if self.featureSelection.get() == 1:
pass
def createClassifyTab(self,nb):
page2 = ttk.Frame(nb)
nb.add(page2,text="Classify")
你有
frameCheckBox.bind("<Configure>",self.resize(canvasScroll))
这意味着
result = self.resize(canvasScroll)
frameCheckBox.bind("<Configure>", result)
所以你没有分配函数但是你执行了resize
并分配了它的结果。
但是resize
returnsNone
所以你终于得到了
frameCheckBox.bind("<Configure>", None)
bind()
(类似于 command=
)需要回调——这意味着没有 ()
和参数的函数名——像这样
frameCheckBox.bind("<Configure>", self.resize)
因为你想发送额外的参数(并跳过 event
默认情况下由 bind
发送)你必须使用 lambda
frameCheckBox.bind("<Configure>", lambda event: self.resize(canvasScroll))