【问题标题】:Enabling the "setgrid" option for a Tkinter widget为 Tkinter 小部件启用“setgrid”选项
【发布时间】:2015-05-21 22:54:49
【问题描述】:

我正在使用 Tkinter 的 grid 几何管理器在第 2 列中生成一个带有水平滚动文本的表格。我尝试创建一个位于第 2 列(作为整个框架的子项)并跨越的 Listbox 小部件所有的行。这似乎很有希望,直到列表框中的文本行明显与父网格的行不对齐。我一直在徒劳地寻找一种方法来填充列表框中的每一行文本以使行匹配;但即使这是可能的,我更喜欢更通用、不那么笨拙的解决方案。

我最近偶然发现了 Gridded Geometry Management 的 description,它暗示了一个小部件的 setgrid 选项。它声称完全符合我的要求:即“[确定]此小部件是否控制其顶级窗口的大小调整网格。”我尝试在我的 Listbox 小部件中启用此选项,但无济于事。我是否以某种方式误解了 setgrid 的目的/用法?

(要查看下面代码的问题,请使用Select FileSelect Folder 按钮将多个音频文件加载到文件列表中。)

#! /usr/bin/env python

#################################################
# This tool allows the user to select audio files 
# (or folders containing audio files) and subject 
# them to loudness analysis.
#################################################

import sys
import os
import codecs
import re
import Tkinter
from Tkinter import *
import tkFileDialog
from os import walk
from os import path
from Tkinter import Tk, Text, BOTH, W, N, E, S
from ttk import Frame, Button, Label, Style, Progressbar
from ScrolledText import *
from progressbar import ProgressBar

class Leveler_tk(Frame):
    fileList = []
    allowedExtensions = ['mp3','mp2','m4a','aiff','wav']

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.style = Style()
        self.style.theme_use("default")
        self.pack(fill=BOTH, expand=1)

        self.columnconfigure(1, weight=1)
        self.columnconfigure(2, weight=1)
        self.columnconfigure(2, pad=250)
        self.columnconfigure(3, weight=1)
        self.columnconfigure(4, weight=1)
        self.columnconfigure(5, weight=1)

        lbl1 = Label(self, text="Analyze")
        lbl1.grid(pady=4, padx=5,row=0,column=0)

        lbl2 = Label(self, text="Adjust")
        lbl2.grid(pady=4, padx=5,row=0,column=1)

        lbl3 = Label(self, text="File")
        lbl3.grid(pady=4, padx=5,row=0,column=2)

        lbl4 = Label(self, text="Integrated\nLoudness")
        lbl4.grid(pady=4, padx=5,row=0,column=3)

        lbl5 = Label(self, text="LRA")
        lbl5.grid(pady=4, padx=5,row=0,column=4)

        lbl6 = Label(self, text="Peak")
        lbl6.grid(pady=4, padx=5,row=0,column=5)

        lbl7 = Label(self, text="Progress")
        lbl7.grid(pady=4, padx=5,row=0,column=6)

        lbl8 = Label(self, text="Meets\nSpecs?")
        lbl8.grid(sticky=W, pady=4, padx=5,row=0,column=7)

        file_btn = Button(self, text="Select File",command=self.selectFile)
        file_btn.grid(row=1,rowspan=2, column=8,padx=5,pady=4)

        folder_btn = Button(self, text="Select Folder", command=self.selectFolder)
        folder_btn.grid(row=3, rowspan=2, column=8,padx=5,pady=4)

    def render(self):
        count = 0
        filebox = Listbox(self,selectmode=EXTENDED,setgrid=1)
        scrollbar = Scrollbar(filebox, orient=HORIZONTAL)
        scrollbar.config(command=filebox.xview)
        filebox.grid(row=1, column=2, rowspan=len(self.fileList), columnspan=1, sticky=N+S+E+W)
        filebox.config(xscrollcommand=scrollbar.set)
        scrollbar.pack(side=BOTTOM, fill=X)
        for file in self.fileList:
            analyze = IntVar()
            adjust = IntVar()
            Radiobutton(self, text="", variable=analyze, value=count, borderwidth=0).grid(row=count+1, column=0)
            Radiobutton(self, text="", variable=adjust,  value=count, borderwidth=0).grid(row=count+1, column=1)
            filebox.insert(END, file + "\n")
            Progressbar(self, orient=HORIZONTAL,length=100, mode='determinate').grid(row=count+1, column=6)
            count += 1

    def addToList(self, name):
        dot = re.search("\.(?=[^.]*$)",name)
        extension = name[dot.end():]
        if extension in self.allowedExtensions and not name in self.fileList:
            self.fileList.append(name)

    def selectFile(self):
        input = tkFileDialog.askopenfilename(filetypes = [('MP3', '*.mp3'), ('MP2', '*.mp2'), ('M4A', '*.m4a'), ('AIFF', '*.aiff'), ('WAV', '*.wav')], multiple = 1)
        for el in input:
            if os.path.isfile(el) and ".DS_Store" not in el:
                try:
                    self.addToList(el)
                except:
                    tkMessageBox.showerror("Some error")
        self.render()

    def selectFolder(self):
        input = tkFileDialog.askdirectory()
        for (dirpath, dirnames, filenames) in walk(input):
            for name in filenames:
                if name != ".DS_Store":
                    self.addToList(dirpath + "/" + name)
        self.render()

def main():
    root = Tk()
    app = Leveler_tk(root)
    root.mainloop()

if __name__ == "__main__":
    main()

【问题讨论】:

    标签: python tkinter gridlayoutmanager


    【解决方案1】:

    我认为你误解了setgrid

    这样一个具有自然大小的小部件基于像素以外的东西(例如文本小部件,其大小基于字符)可以防止父级将其设置为不自然的大小(例如: 20.5 个字符)。使用setgrid,当您以交互方式调整窗口大小时,它将以网格单位(例如:字符高度或宽度)而不是像素来调整大小。

    setgrid 不会阻止调整大小,而是确保调整大小发生在某个其他单位的倍数处。

    以下是 tcl/tk 手册中setgrid 选项的完整、权威参考:

    指定一个布尔值,确定此小部件是否控制 其顶级窗口的大小调整网格。此选项通常是 用于文本小部件,其中小部件中的信息具有 自然大小(字符的大小),它对 窗口的尺寸是这些单位的整数。这些 自然窗口大小形成一个网格。如果 setGrid 选项设置为 true 然后小部件将与窗口管理器进行通信,以便当 用户以交互方式调整包含 小部件,窗口的尺寸将显示给用户 网格单位和窗口大小将是 约束为整数个网格单元。请参阅网格部分 GEOMETRY MANAGEMENT 在 wm 手册条目中了解更多详细信息。

    【讨论】:

    • 非常感谢布莱恩;感谢您对setgrid 的澄清,我肯定是找错了树。您是否知道任何方法可以使单列水平滚动,同时保持其与网格中其他行的对齐?
    猜你喜欢
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 2022-11-16
    相关资源
    最近更新 更多