You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter中PanedWindow嵌入tkScrolledFrame后内容丢失或拉伸异常

求助:Tkinter中PanedWindow结合ScrolledFrame的内容显示问题

问题背景

为展示句子中的信息,尝试多种方案后选择使用PanedWindow,初始实现代码如下:

def create_widgets(self):
    lbl_dir_eval = tk.Label(self, text="Information extracted from document" + self.docname.get(),
                            font=("Arial", 12))
    lbl_dir_eval.grid(row=0, column=0)

    # Create a widget to contain the sentences
    # a paned window is the best option for displaying one sentence per line
    width = round(self.winfo_screenwidth() // 1.6)
    height = round(self.winfo_screenheight() // 1.8)
    self.pan = tk.PanedWindow(self, width=width, height=height, orient=tk.VERTICAL)
    self.pan.grid(row=1, column=0, columnspan=2)

    accept = tk.Button(self, text="Accept document")
    accept.grid(row=2, column=0)
    reject = tk.Button(self, text="Reject document")
    reject.grid(row=2, column=1)

def add_sentence_display(self, sentence):
    frame = tk.Frame(self.pan)
    frame.pack(side=tk.LEFT)

    for token in sentence['sentence']:
        if type(token) is tuple:
            label = tk.LabelFrame(frame, text=token[1])
            label.pack(side='left')
            content = tk.Label(label, text=token[0])
            content.pack()
        else:
            label = tk.Label(frame, text=token)
            label.pack(side='left')
    self.pan.add(frame, stretch="always")

此时出现内容溢出问题:句子过长会向右超出窗口,句子过多会向下溢出,且"Accept document"和"Reject document"按钮会超出屏幕范围。

尝试的解决方案及异常

为解决溢出问题,将PanedWindow放入ScrolledFrame中,修改后的代码如下:

def create_widgets(self):
    lbl_dir_eval = tk.Label(self, text="Information extracted from document" + self.docname.get(),
                            font=("Arial", 12))
    lbl_dir_eval.grid(row=0, column=0)

    # frame to contain extraction display
    # it needs scrollbars because contents overflow the widget
    width = round(self.winfo_screenwidth() // 1.6)
    height = round(self.winfo_screenheight() // 1.8)
    self.sf = tkscrolledframe.ScrolledFrame(self, width=width, height=height, scrollbars="both") # maybe , use_ttk=True)
    self.sf.grid(row=1, column=0, columnspan=2)

    # Create a widget to contain the sentences
    # a paned window is the best option for displaying one sentence per line
    self.pan = self.sf.display_widget(tk.PanedWindow)
    self.pan.configure(orient=tk.VERTICAL, width=width, height=height)

    accept = tk.Button(self, text="Accept document")
    accept.grid(row=2, column=0)
    reject = tk.Button(self, text="Reject document")
    reject.grid(row=2, column=1)

def add_sentence_display(self, sentence):
    frame = tk.Frame(self.pan)
    frame.pack(side=tk.LEFT)

    for token in sentence['sentence']:
        if type(token) is tuple:
            label = tk.LabelFrame(frame, text=token[1])
            label.pack(side='left')
            content = tk.Label(label, text=token[0])
            content.pack()
        else:
            label = tk.Label(frame, text=token)
            label.pack(side='left')
    self.pan.add(frame) # maybe , stretch="always")

但此时出现两种异常:

  • 设置stretch参数时,内容会被拉伸变形,无法正常阅读
  • 不设置stretch参数时,内容闪现后大部分消失,仅少量可见

目前无法找到清晰显示所有内容的方法,不清楚大量内容消失的原因,特此求助。

最小可复现示例

import tkinter as tk
import tkscrolledframe


class View(tk.Frame):
    def __init__(self, parent):
        print("View init")
        super().__init__(parent)
        self.grid()
        self.parent = parent
        self.extraction = []
        self.docname = tk.StringVar(value="")

        self.create_widgets()
        print("View instantiated")

    def create_widgets(self):
        lbl_dir_eval = tk.Label(self, text="Information extracted from document" + self.docname.get(),
                                font=("Arial", 12))
        lbl_dir_eval.grid(row=0, column=0)

        # frame to contain extraction display
        # it needs scrollbars because contents overflow the widget
        width = round(self.winfo_screenwidth() // 1.6)
        height = round(self.winfo_screenheight() // 1.8)
        self.sf = tkscrolledframe.ScrolledFrame(self, width=width, height=height, scrollbars="both", use_ttk=True)
        self.sf.grid(row=1, column=0, columnspan=2)

        # Create a widget to contain the sentences
        # a paned window is the best option for displaying one sentence per line
        self.pan = self.sf.display_widget(tk.PanedWindow)
        self.pan.configure(orient=tk.VERTICAL, width=width, height=height)

        accept = tk.Button(self, text="Accept document")
        accept.grid(row=2, column=0)
        reject = tk.Button(self, text="Reject document")
        reject.grid(row=2, column=1)

    def add_sentence_display(self, sentence):
        frame = tk.Frame(self.pan)
        frame.pack(side=tk.LEFT)
        print('sentence')
        for token in sentence['sentence']:
            if type(token) is tuple:
                label = tk.LabelFrame(frame, text=token[1])
                label.pack(side='left')
                content = tk.Label(label, text=token[0])
                content.pack()
            else:
                label = tk.Label(frame, text=token)
                label.pack(side='left')
        self.pan.add(frame) #, stretch="never")

    def run(self):
        print("Extractor running")


def main(window):
    view = View(window)
    view.run()
    return view


if __name__ == "__main__":
    window = tk.Tk()
    window.title("IRenE")
    width = round(window.winfo_screenwidth() // 1.5)
    height = round(window.winfo_screenheight() // 1.5)
    window.geometry(str(width) + 'x' + str(height))

    view = main(window)
    sentence = {'sentence': [' 3  Applied Energy 259 (2020) 114240  The first ', ('condenser', 'EQUIPMENT'), ' operates with water as a coolant ', ('at 20 ºC', 'DEGREE'), ', and the second one with ', ('methanol', 'COMPOUND'), ' at −20 ', ('ºC.', 'DEGREE'), ' The ', ('pyrolysis', 'PROCESS'), ' oil is captured in vessels at the bottom of the ', ('condensers', 'EQUIPMENT'), ', and uncondensed vapor goes through an impact separator (IP) and an electrostatic ', ('precipitator', 'EQUIPMENT'), ' (EP), which separate the remaining oil ', ('fraction', 'FRACTION'), ' from the gas.']}
    for i in range(100):
        view.add_sentence_display(sentence)
    window.mainloop()

内容的提问来源于stack exchange,提问作者farreres

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 20:50:54