Tkinter中的滚动条在文本widg中

2024-04-26 21:53:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Tkinter的文本小部件内的滚动条中设置有问题。我知道,最好使用网格来定位小部件,但我希望将小部件设置在具有指定高度和宽度的绝对位置(图形用户界面图片上的x,y-红点)。

我的代码:

from Tkinter import *
from ttk import *

class NotebookDemo(Frame):

    def __init__(self):      
        Frame.__init__(self)       
        self.pack(expand=1, fill=BOTH)
        self.master.title('Sample')
        self.master.geometry("650x550+100+50")
        self._initUI()

    def _initUI(self):
        self._createPanel()

    def _createPanel(self):

        # create frame inside top level frame
        panel = Frame(self)    
        panel.pack(side=TOP, fill=BOTH, expand=1)

        # create the notebook
        nb = Notebook(panel)
        nb.pack(fill=BOTH, expand=1, padx=2, pady=3)        
        self._FirstTab(nb)


    def _FirstTab(self, nb):

        # frame to hold content
        frame = Frame(nb)

        #textbox
        txtOutput = Text(frame, wrap = NONE, height = 17, width = 70)
        txtOutput.place(x=10, y=75)

        #button
        btnStart = Button(frame, text = 'Start', underline=0)
        btnStart.place(x=220, y=380)

        #scrollbar
        #vscroll = Scrollbar(frame, orient=VERTICAL, command=txtOutput.yview)
        #txtOutput['yscroll'] = vscroll.set
        #vscroll.pack(side=RIGHT, fill=Y)
        #txtOutput.pack(fill=BOTH, expand=Y)

        #add to notebook (underline = index for short-cut character)
        nb.add(frame, text='TAB 1', underline=0, padding=2)

if __name__ == '__main__':
    app = NotebookDemo()
    app.mainloop()

GUI:

如果我取消注释这部分代码(设置滚动条):

vscroll = Scrollbar(frame, orient=VERTICAL, command=txtOutput.yview)
txtOutput['yscroll'] = vscroll.set
vscroll.pack(side=RIGHT, fill=Y)

我的滚动条位于所有窗口内,而不是文本框内:

enter image description here

但我当然希望在文本框小部件(黑色边框)内有滚动条。 如果我对文本框使用pack函数:

txtOutput.pack(fill=BOTH, expand=Y)

文本小部件填充整个窗口…:

enter image description here

我真的不知道怎么解决这个问题。 任何帮助都将不胜感激。 谢谢您!

编辑:

当然,我也可以使用带有滚动条的place方法,但是我不能更改它们的长度,因为它没有属性length。

vscroll.place(x=573, y=75)

enter image description here


Tags: self部件defplacefillframesidepack
2条回答

placepack这样的不同几何管理器不能很好地混合。我为您提供四种选择:

使用父帧

在与文本框完全相同的位置创建一个新的Frame。在这个框架中,您可以使用另一个几何图形管理器(我更喜欢pack)使布局显示为您想要的样子。

使用ScrolleText

使用ScrolledTextTkinter模块将上面的解决方案预先制作好。注意,这个小部件不使用ttk,所以滚动条样式并不能真正适应操作系统的外观。只需使用import ScrolledText,并用ScrolledText.ScrolledText(...)替换代码中的Text创建。

使用滚动条的位置

如果您使用place作为文本小部件,也可以使用place作为滚动条。place有一些选项允许您在位置和大小上相对于另一个小部件放置小部件(即:您可以沿文本小部件的右边缘放置滚动条,并使其与文本小部件一样高)。See Bryan's answer

不用地方

就这么简单。使用gridpack代替,除非确实需要使用place

虽然我很少推荐place,但是当您利用配置选项时,它非常强大。例如,您可以使用in_指定要相对于其放置此小部件的小部件。可以使用relx指定相对x坐标,也可以使用relheight指定高度。

在您的情况下,您可以尝试以下方法:

vscroll.place(in_=txtOutput, relx=1.0, relheight=1.0, bordermode="outside")

如果你想让人产生一种错觉,即滚动条嵌入文本小部件中,这在某些平台上是很常见的,我建议你将文本小部件和滚动条放在一个框架中,你可以使用pack将小部件放在框架中,然后继续使用place将组合放在你想要的任何地方。

例如:

txtFrame = Frame(frame, borderwidth=1, relief="sunken")
txtOutput = Text(txtFrame, wrap = NONE, height = 17, width = 70, borderwidth=0)
vscroll = Scrollbar(txtFrame, orient=VERTICAL, command=txtOutput.yview)
txtOutput['yscroll'] = vscroll.set

vscroll.pack(side="right", fill="y")
txtOutput.pack(side="left", fill="both", expand=True)

txtFrame.place(x=10, y=75)

相关问题 更多 >