【问题标题】:Tkinter scrollbar doesn't fill frameTkinter 滚动条不填满框架
【发布时间】:2015-12-19 23:23:26
【问题描述】:

我正在尝试制作一个根据用户的分辨率进行更改的 GUI。我对 Python 还是很陌生,但我已经设法做到了这一点。我正在努力寻找为什么滚动条没有使用给它们的所有空间。这会导致它们后面的框架可见。

root = Tk()

screen_height = root.winfo_screenheight()
screen_width = root.winfo_screenwidth()

h = (screen_height / 800)
w = (screen_width / 1300)

frame = ['topleft', 'topmid', 'topright',
     'bottomleft', 'bottommid']
multiplier = [300, 200, 800, 500, 100]
height = [0,
      Decimal(h*(multiplier[0]))
      .quantize(Decimal('1.'), rounding=ROUND_UP),
      Decimal(h*(multiplier[1]))
      .quantize(Decimal('1.'), rounding=ROUND_UP),
      Decimal(h*(multiplier[2]))
      .quantize(Decimal('1.'), rounding=ROUND_UP),
      Decimal(h*(multiplier[3]))
      .quantize(Decimal('1.'), rounding=ROUND_UP),
      Decimal(h*(multiplier[4]))
      .quantize(Decimal('1.'), rounding=ROUND_UP)
     ]
width = [0,
     Decimal(w*(multiplier[0]))
     .quantize(Decimal('1.'), rounding=ROUND_UP),
     Decimal(w*(multiplier[1]))
     .quantize(Decimal('1.'), rounding=ROUND_UP),
     Decimal(w*(multiplier[2]))
     .quantize(Decimal('1.'), rounding=ROUND_UP),
     Decimal(w*(multiplier[3]))
     .quantize(Decimal('1.'), rounding=ROUND_UP),
     Decimal(w*(multiplier[4]))
     .quantize(Decimal('1.'), rounding=ROUND_UP),
     Decimal(w*(multiplier[4]))
     .quantize(Decimal('1.'), rounding=ROUND_UP),
    ]

topleft = Frame(root,
            bg = 'black', bd='3',
            height = height[1], width = width[1],
            relief='flat'
            ).grid(row = height[0], column = width[0],
                   rowspan = height[1], columnspan = width[1])
topmid = Frame(root,
           bg = 'yellow', bd='3',
           height = height[2], width = width[2],
           relief='flat'
           ).grid(row = height[0], column = width[1],
                  rowspan = height[2], columnspan = width[2])
bottommid = Frame(root,
              bg = 'pink', bd ='3',
              height = height[5], width = width[5],
              relief='flat'
              ).grid(row = height[2], column = width[1],
                     rowspan = height[5], columnspan = width[5])
bottomright = Frame(root,
                bg = 'blue', bd='3',
                height = height[5], width = width[5],
                relief='flat'
                ).grid(row = height[2], column = width[1]+width[5],
                       rowspan = height[5], columnspan = width[5])

class file_selector:
def __init__(self):
    global fs_scrollbar, fs_listbox, check
    bottomleft = Frame(root,
               bg = 'white', bd='3',
               height = height[4], width = width[4],
               relief='flat'
               ).grid(row= height[1], column= width[0],
                      rowspan= height[4], columnspan= width[4])

    self.fs_scrollbar = Scrollbar(bottomleft,
                          orient = VERTICAL
                          )

    self.fs_listbox = Listbox(bottomleft,
                      bg = 'white',
                      relief = 'flat',
                      yscrollcommand = self.fs_scrollbar.set
                      )

    self.check = print(self.fs_listbox.curselection())

    self.fs_listbox.bind('<ButtonRelease-1>', self.check)

    self.fs_scrollbar['command'] = self.fs_listbox.yview

    file_selector.widgets(self)

def widgets(self):        

    self.fs_scrollbar.grid(row = height[1], column = (width[4]-(width[4]*Decimal(0.05)).quantize(Decimal('1.'), rounding=ROUND_UP)),
                           rowspan = height[4], columnspan = ((width[4]*Decimal(0.05)).quantize(Decimal('1.'), rounding=ROUND_UP)),
                           sticky= N+E+S+W
                           )

    for file in os.listdir(os.curdir):
        if file.endswith(".txt"):
            self.fs_listbox.insert(END, file)

    self.fs_listbox.grid(row = height[1], column = width[0],
                         rowspan = height[4], columnspan = (width[4]-(width[4]*Decimal(0.05)).quantize(Decimal('1.'), rounding=ROUND_UP)),
                         sticky = N+E+S+W
                         )



class text_editor:
def __init__(self):
    global te_scrollbar, te_text
    topright = Frame(root,
             bg = 'red', bd='3',
             height = height[3], width = width[3],
             relief='flat'
             ).grid(row=height[0], column= width[4],
                    rowspan= height[3], columnspan= width[3])

    self.te_scrollbar = Scrollbar(topright,
                                  orient = VERTICAL
                                  )

    self.te_text = Text(topright,
                bg = 'white',
                yscrollcommand = self.te_scrollbar.set
                )

    self.te_scrollbar['command'] = self.te_text.yview

    text_editor.widgets(self)

def widgets(self):
    with open('test1.txt', 'r') as self.file:
         self.file = self.file.read()

    self.te_scrollbar.grid(row = height[0], column = (width[4]+width[3]-(width[3]*Decimal(0.05)).quantize(Decimal('1.'), rounding=ROUND_UP)),
                           rowspan = height[3], columnspan = ((width[3]*Decimal(0.05)).quantize(Decimal('1.'), rounding=ROUND_UP)),
                           sticky = N+S
                           )

    self.te_text.insert(END, self.file)

    self.te_text.grid(row = height[0], column = width[4],
                      rowspan = height[3], columnspan = (width[3]-(width[3]*Decimal(0.05)).quantize(Decimal('1.'), rounding=ROUND_UP)),
                      sticky = N+E+S+W
                      )

file_selector()
text_editor()

对于糟糕的代码,提前抱歉,Tkinter 没有很好的文档记录(我也不是很擅长)。

【问题讨论】:

  • bottomleft = Frame(...).grid(...) 会将None 分配给bottomleft,因为grid() 返回None - 使用bottomleft = Frame(...) ; bottomleft.grid(...)

标签: python tkinter scrollbar


【解决方案1】:

您不需要进行所有这些计算——tkinter 非常擅长为您计算几何。

您在使用网格时犯了几个非常常见的错误。当容器(例如:框架)中有额外空间时,网格将为具有正“权重”的行和列分配额外空间。默认情况下,网格行和列的权重为 0(零),这意味着它们不会获得任何额外空间。

根据经验,内部小部件使用网格的每一帧都需要至少有一行和一列具有正权重。你可以使用grid_rowconfiguregrid_columnconfigure 命令来实现。在您的情况下,您需要为至少一行(可能是底行)赋予 1(一)的权重。

您还有另一个非常常见的问题。考虑这行代码和其他类似的代码:

topleft = Frame(...).grid(...)

上面将始终将topleft 设置为None,因为这是grid 返回的内容。因此,您认为进入topleft 的任何小部件实际上都进入了根窗口,因为将None 指定为父窗口或主窗口与提供根窗口相同。

然而,在我看来,你还有更大的问题。将一个网格用于具有多个小部件的整个应用程序是非常难以做到的。相反,您需要采取“分而治之”的方法。

例如,您的 GUI 显然有两个主要区域:左侧和右侧。所以我会先制作两个框架,每边一个。这样,右侧的任何 grid 或 pack 命令都不会影响左侧的 grid 或 pack 命令,反之亦然。

左侧似乎也分为两部分:顶部带有彩色框架,底部是列表框和滚动条。我建议将左侧分成两半。同样,在左下角使用 grid 或 pack 不会影响在左上角使用 grid 或 pack。这将使解决您的布局问题变得更加容易。

【讨论】:

    猜你喜欢
    • 2018-07-13
    • 2013-04-17
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-24
    相关资源
    最近更新 更多