如何向使用 tkinter 制作的窗口添加滚动条

Gio*_* PY 4 python tkinter scrollbar

一个简单的问答游戏

\n\n

我得到了这段代码,我需要滚动条,我尝试搜索如何在 stackoverflow 上添加它(ScrolledWindow with tix...),但我仍然无法得到正常工作的东西。有人可以帮助我吗?

\n\n
from tkinter import *\nfrom random import randint\n\nroot = Tk()\nroot.title("Quiz")\nroot.geometry("400x300")\n\n\nclass Window:\n\n    def __init__(self, question, answer):\n        self.text = [question, answer]\n        self.createLabel()\n        # self.createText()\n        self.createEntry()\n        self.createButton()\n\n    def retrieve_input(self):\n        # inputValue = self.textBox.get("1.0", "end-1c")\n        # print(inputValue)\n        if self.mystring.get() == self.text[1]:\n            print("Esatto. \xc3\xa8 " + self.text[1])\n            self.left[\'text\'] = "Esatto"\n\n    def createLabel(self):\n        self.labelframe = LabelFrame(root, text="Domanda:")\n        self.labelframe.pack(fill="both", expand="yes")\n        self.left = Label(self.labelframe, text=self.text[0])\n        self.left.pack()\n\n    def createText(self):\n        self.textBox = Text(height=1)\n        self.textBox.pack()\n\n    def createEntry(self):\n        self.mystring = StringVar()\n        self.myentry = Entry(root, textvariable=self.mystring).pack()\n\n    def createButton(self):\n        self.but = Button(text="Click", command=self.retrieve_input)\n        self.but.pack()\n\n\nfor i in range(10):\n    one = randint(1, 10)\n    two = randint(1, 10)\n    Window("Quanto fa " + str(one) + "+" + str(two) + "?", str(one + two))\n\nroot.mainloop()\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

输出

\n
\n\n

在此输入图像描述

\n

fur*_*ras 5

有了ScrolledFrame它就可以看起来像这样

\n\n

在此输入图像描述

\n\n
    \n
  • 我重命名WindowQuestion因为它更有意义
  • \n
  • 我使用self.questionandself.answer代替是 self.text = [question, answer]为了使其更具可读性。
  • \n
  • 我将类和函数放在前面root = tk.Tk()以使其更具可读性。
  • \n
  • 我使用import tkinter as tk而不是from tkinter import * 使其更具可读性。
  • \n
\n\n

Question从中获取内部框架ScrolledFrame并用作 的父级LabelFrame。其他小部件用作labelframe父部件。

\n\n

顺便说一句:你有entry = Entry(..).pack()which分配Noneentry因为pack()// returns 。我放入下一行,现在我可以直接从中获取文本(无需grid()place()Nonepack()EntryStringVar

\n\n

代码

\n\n
import tkinter as tk\nfrom random import randint\n\n# --- classes ---\n\nclass ScrolledFrame(tk.Frame):\n\n    def __init__(self, parent, vertical=True, horizontal=False):\n        super().__init__(parent)\n\n        # canvas for inner frame\n        self._canvas = tk.Canvas(self)\n        self._canvas.grid(row=0, column=0, sticky=\'news\') # changed\n\n        # create right scrollbar and connect to canvas Y\n        self._vertical_bar = tk.Scrollbar(self, orient=\'vertical\', command=self._canvas.yview)\n        if vertical:\n            self._vertical_bar.grid(row=0, column=1, sticky=\'ns\')\n        self._canvas.configure(yscrollcommand=self._vertical_bar.set)\n\n        # create bottom scrollbar and connect to canvas X\n        self._horizontal_bar = tk.Scrollbar(self, orient=\'horizontal\', command=self._canvas.xview)\n        if horizontal:\n            self._horizontal_bar.grid(row=1, column=0, sticky=\'we\')\n        self._canvas.configure(xscrollcommand=self._horizontal_bar.set)\n\n        # inner frame for widgets\n        self.inner = tk.Frame(self._canvas, bg=\'red\')\n        self._window = self._canvas.create_window((0, 0), window=self.inner, anchor=\'nw\')\n\n        # autoresize inner frame\n        self.columnconfigure(0, weight=1) # changed\n        self.rowconfigure(0, weight=1) # changed\n\n        # resize when configure changed\n        self.inner.bind(\'<Configure>\', self.resize)\n        self._canvas.bind(\'<Configure>\', self.frame_width)\n\n    def frame_width(self, event):\n        # resize inner frame to canvas size\n        canvas_width = event.width\n        self._canvas.itemconfig(self._window, width = canvas_width)\n\n    def resize(self, event=None): \n        self._canvas.configure(scrollregion=self._canvas.bbox(\'all\'))\n\nclass Question:\n\n    def __init__(self, parent, question, answer):\n        self.parent = parent\n        self.question = question\n        self.answer = answer\n        self.create_widgets()\n\n    def get_input(self):\n        value = self.entry.get()\n        print(\'value:\', value)\n        if value == self.answer:\n            print("Esatto. \xc3\xa8 " + self.answer)\n            self.label[\'text\'] = "Esatto"\n\n    def create_widgets(self):\n        self.labelframe = tk.LabelFrame(self.parent, text="Domanda:")\n        self.labelframe.pack(fill="both", expand=True)\n\n        self.label = tk.Label(self.labelframe, text=self.question)\n        self.label.pack(expand=True, fill=\'both\')\n\n        self.entry = tk.Entry(self.labelframe)\n        self.entry.pack()\n\n        self.button = tk.Button(self.labelframe, text="Click", command=self.get_input)\n        self.button.pack()\n\n# --- main ---\n\nroot = tk.Tk()\nroot.title("Quiz")\nroot.geometry("400x300")\n\nwindow = ScrolledFrame(root)\nwindow.pack(expand=True, fill=\'both\')\n\nfor i in range(10):\n    one = randint(1, 10)\n    two = randint(1, 10)\n    Question(window.inner, "Quanto fa {} + {} ?".format(one, two), str(one + two))\n\nroot.mainloop()\n
Run Code Online (Sandbox Code Playgroud)\n