Python的Tkinter水平滚动与按钮不起作用。

huangapple go评论61阅读模式
英文:

Python's Tkinter Horizontal Scroll with Buttons not working

问题

我尝试水平迭代图像按钮。滚动条显示正常,但在滚动时不显示更多项目。此滚动条在垂直滚动时完美运行。请查看以下代码:

英文:

I am trying to iterate image buttons horizontally. Scrollbar appears fine but it is not showing up more items when scroll. This scrollbar works perfectly fine on vertical scroll. Please review below code:

`from tkinter_scroll import *
from tkinter import *

for index in range(i):
    if len(PHOTOS[index]) > 0:
        for k,photo in enumerate(PHOTOS[index]):
            img_text = ""
            btn= Button(scrollable_body, highlightbackground='red', fg='red', text=img_text,bg='white',border='0', image=photo, command = lambda index=index, k=k: put_sprite(index,k), compound=LEFT, width='100', height='110')
            btn.pack(side="left", fill="both", expand="no", padx="5", pady="5")
            BTNS.append(btn)
scrollable_body.update()

#===== Tkinter Class ====
import tkinter as tk
from tkinter import ttk

class Scrollable(ttk.Frame):
    def __init__(self, frame, width=16):
        scrollbar = tk.Scrollbar(frame, width=width, orient='horizontal')
        scrollbar.pack(side=tk.BOTTOM, fill=tk.X, expand=True)
        
        self.canvas = tk.Canvas(frame, width=800, height=120, bg='white',xscrollcommand=scrollbar.set)
        self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=self.canvas.xview)
        self.canvas.bind('<Configure>', self.__fill_canvas)
        tk.Frame.__init__(self, frame)
        self.windows_item = self.canvas.create_window(
            0, 0, window=self, anchor=tk.W)
    def __fill_canvas(self, event):
        "Enlarge the windows item to the canvas width"
        canvas_width = event.width
        self.canvas.itemconfig(self.windows_item, width=canvas_width)
    def update(self):
        "Update the canvas and the scrollregion"
        self.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox(self.windows_item))

答案1

得分: 1

以下是翻译好的内容:

你的类 Scrollable 存在一些问题:

  • Scrollable 继承自 ttk.Frame,但你调用了 tk.Frame.__init__(...)
  • 如果你想要水平滚动,为什么将内部帧的宽度(即 Scrollable 的实例)设置为与画布相同?
  • 最好绑定内部帧的 <Configure> 事件,并在绑定回调中更新画布的 scrollregion

以下是更新后的 Scrollable 类和使用它的示例:

import tkinter as tk
from tkinter import ttk

class Scrollable(ttk.Frame):
    def __init__(self, frame, width=16):
        scrollbar = tk.Scrollbar(frame, width=width, orient='horizontal')
        scrollbar.pack(side=tk.BOTTOM, fill=tk.X)

        self.canvas = tk.Canvas(frame, width=800, height=120, bg='white', xscrollcommand=scrollbar.set)
        self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=self.canvas.xview)
        ttk.Frame.__init__(self, self.canvas)
        self.windows_item = self.canvas.create_window(0, 0, window=self, anchor=tk.NW)
        self.bind("<Configure>", lambda e: self.canvas.config(scrollregion=self.canvas.bbox(self.windows_item)))

root = tk.Tk()

scrollable = Scrollable(root)

for i in range(20):
    tk.Button(scrollable, text=i+1, width=20).pack(side=tk.LEFT, padx=5, pady=5)

root.mainloop()

结果:

Python的Tkinter水平滚动与按钮不起作用。
1: https://i.stack.imgur.com/81NR9.png

英文:

There are few issues in your class Scrollable:

  • Scrollable inherits from ttk.Frame, but you called tk.Frame.__init__(...)
  • if you want to scroll horizontally, why do you set the width of the internal frame (i.e. instance of Scrollable) to same as the canvas?
  • it is better to bind &lt;Configure&gt; event of the internal frame and update scrollregion of the canvas inside the bind callback

Below is the updated class Scrollable and an example of using it:

import tkinter as tk
from tkinter import ttk

class Scrollable(ttk.Frame):
    def __init__(self, frame, width=16):
        scrollbar = tk.Scrollbar(frame, width=width, orient=&#39;horizontal&#39;)
        scrollbar.pack(side=tk.BOTTOM, fill=tk.X)

        self.canvas = tk.Canvas(frame, width=800, height=120, bg=&#39;white&#39;, xscrollcommand=scrollbar.set)
        self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=self.canvas.xview)
        ttk.Frame.__init__(self, self.canvas)
        self.windows_item = self.canvas.create_window(0, 0, window=self, anchor=tk.NW)
        self.bind(&quot;&lt;Configure&gt;&quot;, lambda e: self.canvas.config(scrollregion=self.canvas.bbox(self.windows_item)))

root = tk.Tk()

scrollable = Scrollable(root)

for i in range(20):
    tk.Button(scrollable, text=i+1, width=20).pack(side=tk.LEFT, padx=5, pady=5)

root.mainloop()

Result:

Python的Tkinter水平滚动与按钮不起作用。

huangapple
  • 本文由 发表于 2023年5月22日 18:24:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76305216.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定