我正在嘗試在 tkinter 中創建一個可滾動的單選按鈕串列,但我沒有讓它作業。我已經嘗試將我的單選按鈕串列嵌入到各種 tkinter 容器中,但我得到了相同的結果,即滾動條不起作用并且單選按鈕串列沒有從容器中清除(例如,所以我可以用不同的單選按鈕串列)。我已經搜索了如何做到這一點,但找不到任何東西。這可能嗎?
這是我的示例應用程式:
import tkinter as tk
from tkinter import ttk
class CodeSampleForStackoverflow:
def __init__(self, window):
self.main_window = window
self.mainframe = ttk.Frame(self.main_window, padding = '15 3 12 12')
self.mainframe.grid(column = 0, row = 0, sticky = "W, E, N, S")
self.file_choice = tk.StringVar()
self.contents_list = list()
self.display_folder_btn = ttk.Button(self.mainframe, text = "Display list of choices", width = 20)
self.display_folder_btn.grid(row = 1, column = 0, columnspan = 2)
self.display_folder_btn.bind("<Button-1>", self.list_folder_contents)
self.folder_contents_canvas = tk.Canvas(self.mainframe)
self.scroll_y = tk.Scrollbar(self.folder_contents_canvas, orient="vertical")
self.scroll_y.pack(fill = 'y', side = 'right')
self.folder_contents_canvas.grid(row=2, column = 0, columnspan = 2)
self.folder_contents_frame = tk.Text(self.folder_contents_canvas, height = 7, width = 50, yscrollcommand = self.scroll_y.set)
self.folder_contents_frame.pack(side = "top", fill = "x", expand = False, padx = 20, pady = 20)
def list_folder_contents(self, event):
try:
self.contents_list = ['A dictum nulla auctor id.', 'A porttitor diam iaculis quis.', 'Consectetur adipiscing elit.', \
'Curabitur in ante iaculis', 'Finibus tincidunt nunc.', 'Fusce elit ligula', \
'Id sollicitudin arcu semper sit amet.', 'Integer at sapien leo.', 'Lorem ipsum dolor sit amet', \
'Luctus ligula suscipit', 'Nam vitae erat a dolor convallis', \
'Praesent feugiat quam ac', 'Pretium diam.', 'Quisque accumsan vehicula dolor', \
'Quisque eget arcu odio.', 'Sed ac elit id dui blandit dictum', 'Sed et eleifend leo.', \
'Sed vestibulum fermentum augue', 'Suspendisse pharetra cursus lectus', 'Ultricies eget erat et', \
'Vivamus id lorem mi.']
contents_dict = dict()
self.folder_contents_frame.delete(1.0, 'end')
counter = 0
for i in self.contents_list:
contents_dict[str(counter 1)] = i
counter =1
for (text, value) in contents_dict.items():
#self.folder_contents_frame.insert(1.0, text "\t" value "\n")
ttk.Radiobutton(self.folder_contents_frame, text = value, variable = self.file_choice, value = text, style = "TRadiobutton").grid(column = 0, columnspan = 2, sticky = tk.W)
self.scroll_y.config(command = self.folder_contents_frame.yview)
except Exception as exc:
print(exc)
#-----------------------------------------
def main():
root = tk.Tk()
root.title('Scrollable radiobutton list')
root.geometry("500x600")
tabs = ttk.Notebook(root)
tabs.pack(fill = "both")
scrollable_radiobutton_list_frame = ttk.Frame(tabs)
tabs.add(scrollable_radiobutton_list_frame, text = "Scrollable radiobutton list")
my_checker = CodeSampleForStackoverflow(window = scrollable_radiobutton_list_frame)
root.mainloop()
if __name__ == '__main__':
main()
如果您注釋掉 list_folder_contents 方法中創建單選按鈕的行并取消注釋它上面的行,您可以看到我希望它的行為方式,但使用單選按鈕而不是純文本。
編輯:附帶問題:如果有人知道為什么(在文本版本中)這些專案以相反的順序添加,我也很感激那里的指導。
感謝您提供的任何幫助!
uj5u.com熱心網友回復:
解決這個問題的一種方法是創建一個可滾動的框架類并使用它。我有一個可滾動的框架類,取自 SO(我不記得確切的答案)并根據我的需要進行了修改,這應該適用于您的應用程式。
import tkinter as tk
from tkinter import ttk
class ScrollFrame(tk.Frame):
def __init__(self, parent):
super().__init__(parent) # create a frame (self)
self.canvas = tk.Canvas(self, borderwidth=0, background="#ffffff") # Canvas to scroll
self.viewPort = tk.Frame(self.canvas, background="#ffffff") # This frame will hold the child widgets
self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.vsb.set) # Attach scrollbar action to scroll of canvas
self.vsb.pack(side="right", fill="y") # Pack scrollbar to right - change as needed
self.canvas.pack(side="left", fill="both", expand=True) # Pack canvas to left and expand to fill - change as needed
self.canvas_window = self.canvas.create_window(
(0,0),
window=self.viewPort,
anchor="nw",
tags="self.viewPort",
) # Add view port frame to canvas
self.viewPort.bind("<Configure>", self.onFrameConfigure)
self.canvas.bind("<Configure>", self.onCanvasConfigure)
self.first = True
self.onFrameConfigure(None) # Initial stretch on render
def onFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def onCanvasConfigure(self, event):
'''Reset the canvas window to encompass inner frame when required'''
canvas_width = event.width
self.canvas.itemconfig(self.canvas_window, width = canvas_width)
def on_mousewheel(self, event):
'''Allows the mousewheel to control the scrollbar'''
self.canvas.yview_scroll(int(-1*(event.delta/120)), "units")
def bnd_mousewheel(self):
'''Binds the mousewheel to the scrollbar'''
self.canvas.bind_all("<MouseWheel>", self.on_mousewheel)
def unbnd_mousewheel(self):
'''Unbinds the mousewheel from the scrollbar'''
self.canvas.unbind_all("<MouseWheel>")
def delete_all(self):
'''Removes all widgets from the viewPort, only works if grid was used'''
children = self.viewPort.winfo_children()
for child in children:
child.grid_remove()
class CodeSampleForStackoverflow:
def __init__(self, window):
self.main_window = window
self.mainframe = ttk.Frame(self.main_window, padding = '15 3 12 12')
self.mainframe.grid(column = 0, row = 0, sticky = "W, E, N, S")
self.file_choice = tk.StringVar()
self.contents_list = list()
self.display_folder_btn = ttk.Button(self.mainframe, text = "Display list of choices", width = 20, command=self.list_folder_contents)
self.display_folder_btn.pack(side="top")
self.folder_contents_frame = ScrollFrame(self.mainframe)
self.folder_contents_frame.pack(side = "top", fill = "x", expand = False, padx = 20, pady = 20)
def list_folder_contents(self):
try:
self.contents_list = ['A dictum nulla auctor id.', 'A porttitor diam iaculis quis.', 'Consectetur adipiscing elit.', \
'Curabitur in ante iaculis', 'Finibus tincidunt nunc.', 'Fusce elit ligula', \
'Id sollicitudin arcu semper sit amet.', 'Integer at sapien leo.', 'Lorem ipsum dolor sit amet', \
'Luctus ligula suscipit', 'Nam vitae erat a dolor convallis', \
'Praesent feugiat quam ac', 'Pretium diam.', 'Quisque accumsan vehicula dolor', \
'Quisque eget arcu odio.', 'Sed ac elit id dui blandit dictum', 'Sed et eleifend leo.', \
'Sed vestibulum fermentum augue', 'Suspendisse pharetra cursus lectus', 'Ultricies eget erat et', \
'Vivamus id lorem mi.']
contents_dict = dict()
self.folder_contents_frame.delete_all()
counter = 0
for i in self.contents_list:
contents_dict[str(counter 1)] = i
counter =1
for (text, value) in contents_dict.items():
ttk.Radiobutton(self.folder_contents_frame.viewPort, text = value, variable = self.file_choice, value = text, style = "TRadiobutton").grid(column = 0, columnspan = 2, sticky = tk.W)
except Exception as exc:
print(exc)
#-----------------------------------------
def main():
root = tk.Tk()
root.title('Scrollable radiobutton list')
root.geometry("500x600")
tabs = ttk.Notebook(root)
tabs.pack(fill = "both")
scrollable_radiobutton_list_frame = ttk.Frame(tabs)
tabs.add(scrollable_radiobutton_list_frame, text = "Scrollable radiobutton list")
my_checker = CodeSampleForStackoverflow(window = scrollable_radiobutton_list_frame)
root.mainloop()
if __name__ == '__main__':
main()
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/430793.html
