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

Tkinter网格布局异常:列宽与行高配置未生效问题求助

问题分析与修复方案

核心问题点

  1. 混合使用布局管理器:主框架frame同时调用pack()和grid(),Tkinter不允许同一组件混用两种布局规则,直接导致布局逻辑冲突。
  2. 第一行文本框拆分错误:需求是一个占5列的右侧文本框,但代码拆成两个组件(占2列+3列),增加布局复杂度且易引发列宽分配异常。
  3. 图片固定宽度限制缩放:图片标签设置width=new_width强制固定宽度,忽略了列权重配置,导致对应列无法随窗口缩放。
  4. 行权重设置不符合需求:第一行权重设为1会随窗口拉伸,但需求是行高适配图片最小高度,应设为0并指定最小高度。
  5. 文本框固定高度:第一行文本框的height=7参数固定了高度,无法自适应图片高度。

修复后的完整代码

import tkinter as tk
from ctypes import windll
import sys
from PIL import Image, ImageTk

windll.shcore.SetProcessDpiAwareness(1)
quitapp = False
maxscreens = 1
lookups = ['AVG', 'BTC', 'ETH', 'USDT']
domesticdict = {}

def show_data(data):
    def search_text(event=None):
        # Clear previous highlights
        text_widget.tag_remove("highlight", "1.0", tk.END)

        # Get the search query
        search_query = search_entry.get().upper()

        if search_query:
            start_pos = "1.0"
            instance_count = 0
            first_instance_pos = None

            while True:
                start_pos = text_widget.search(search_query, start_pos, stopindex=tk.END)
                if not start_pos:
                    break

                if not first_instance_pos:
                    first_instance_pos = start_pos

                instance_count += 1

                end_pos = f"{start_pos}+{len(search_query)}c"
                text_widget.tag_add("highlight", start_pos, end_pos)
                start_pos = end_pos

            text_widget.tag_config("highlight", background="yellow", foreground="black")

            if first_instance_pos:
                text_widget.see(first_instance_pos)

            result_label.config(text=f"Found {instance_count} instances.")
    data_window = tk.Toplevel()
    data_window.title("Domestic Sources for Binance Tokens")

    # search entry button
    search_entry = tk.Entry(data_window)
    search_entry.pack(side=tk.TOP, padx=5, fill=tk.X)
    search_button = tk.Button(data_window, text="Search", command=search_text)
    search_button.pack(side=tk.TOP, padx=5)
    result_label = tk.Label(data_window, text="")
    result_label.pack(side=tk.TOP, padx=5)
    data_window.bind("<Return>", search_text)  # Bind the search_text function to the Enter key

    # Create a frame to hold the Text and Scrollbar widgets
    frame = tk.Frame(data_window)
    frame.pack(expand=True, fill=tk.BOTH, padx=5, pady=5)

    # Create the Text widget
    text_widget = tk.Text(frame, wrap=tk.WORD, background='black', foreground='white')
    text_widget.pack(side=tk.LEFT, expand=True, fill=tk.BOTH)

    # Create the Scrollbar widget
    scrollbar = tk.Scrollbar(frame)
    scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

    # Link the Scrollbar to the Text widget
    text_widget.config(yscrollcommand=scrollbar.set)
    scrollbar.config(command=text_widget.yview)

    for key, value in data.items():
        text_widget.insert(tk.END, f"{key}: {value}\n")

    data_window.mainloop()

def on_image_click(event, data):
    show_data(data)

def create_tkinter_window():
    global domesticdict
    # Create the main window
    root = tk.Tk()
    root.title("Crypto Monitor")
    root.state('zoomed')

    fontname = 'Courier'
    fontsize = 14

    frame = tk.Frame(root, background='black')
    frame.pack(expand=True, fill=tk.BOTH)

    # Create the text boxes - 合并第一行右侧的两个文本框为一个
    text_box_topleft = tk.Text(frame, font=(fontname, fontsize), wrap=tk.WORD, 
                               foreground="white", background='black', bd=20, highlightthickness=0)
    text_box_topright = tk.Text(frame, font=(fontname, fontsize), wrap=tk.WORD, 
                                foreground="white", background='black', bd=20, highlightthickness=0)
    text_box_left = tk.Text(frame, font=(fontname, fontsize), wrap=tk.WORD, 
                            foreground="white", background='black', bd=20, highlightthickness=0)
    text_box_right = tk.Text(frame, font=(fontname, fontsize), wrap=tk.WORD, 
                             foreground="white", background='black', bd=20, highlightthickness=0)

    # load the logo
    image_file = "Crypto Monitor.png"
    image = Image.open(image_file)
    new_width = 500
    aspect_ratio = float(image.height) / float(image.width)
    new_height = int(new_width * aspect_ratio)
    image = image.resize((new_width, new_height), Image.LANCZOS)
    photo = ImageTk.PhotoImage(image)
    # 去掉固定width,让grid控制宽度
    image_label = tk.Label(frame, image=photo, background='black')
    image_label.image = photo  # 保留引用防止图片被回收
    image_label.bind("<Button-1>", lambda event: on_image_click(event, domesticdict))

    # Position the text boxes using the grid geometry manager
    text_box_topleft.grid(row=0, column=0, columnspan=5, padx=0, pady=0, sticky="nsew")
    image_label.grid(row=0, column=5, columnspan=2, padx=0, pady=0, sticky="nsew")
    text_box_topright.grid(row=0, column=7, columnspan=5, padx=0, pady=0, sticky="nsew")  # 改为占5列
    text_box_left.grid(row=1, column=0, columnspan=6, padx=0, pady=0, sticky="nsew")
    text_box_right.grid(row=1, column=6, columnspan=6, padx=0, pady=0, sticky="nsew")

    # Configure the grid to resize with the window
    # 第一行权重设为0,最小高度设为图片高度,确保行高适配图片
    frame.grid_rowconfigure(0, weight=0, minsize=new_height)
    frame.grid_rowconfigure(1, weight=1)  # 第二行占剩余空间
    for i in range(12): 
        frame.grid_columnconfigure(i, weight=1)  # 12列等宽,随窗口缩放

    def on_close():
        global quitapp
        quitapp = True
        root.destroy()
        sys.exit()

    root.protocol("WM_DELETE_WINDOW", on_close)

    try: 
        root.mainloop()
    except KeyboardInterrupt: 
        pass

create_tkinter_window()

关键修改说明

  1. 移除混合布局调用:删除frame.grid(),仅保留frame.pack(expand=True, fill=tk.BOTH),确保布局管理器唯一。
  2. 合并第一行右侧文本框:将拆分的两个文本框合并为一个,设置columnspan=5,匹配需求的布局结构。
  3. 取消图片固定宽度:删除image_label的width=new_width参数,让grid的sticky="nsew"和列权重控制图片宽度,实现随窗口缩放。
  4. 调整行权重与最小高度:第一行设置weight=0和minsize=new_height,保证行高刚好适配图片;第二行设weight=1,占据窗口剩余垂直空间。
  5. 移除文本框固定高度:删除第一行文本框的height=7参数,让高度随行高自适应图片尺寸。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 06:10:06