前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >解决Tkinter中OptionMenu溢出问题

解决Tkinter中OptionMenu溢出问题

原创
作者头像
华科云商小徐
发布2025-01-10 10:13:14
发布2025-01-10 10:13:14
8500
代码可运行
举报
文章被收录于专栏:小徐学爬虫小徐学爬虫
运行总次数:0
代码可运行

在使用 TkinterOptionMenu 小部件时,如果选项列表较多或选项内容较长,可能会导致溢出的问题(例如,选项框变得过大或超出窗口边界)。以下是常见的溢出问题及解决方法:

1、问题背景

当在 Windows 系统下使用 Python 2.7 创建 Tkinter 应用程序时,OptionMenu 的右上角(单击时会显示选项的下拉按钮)被截断在中间。以下代码可以重现此问题:

代码语言:javascript
代码运行次数:0
运行
复制
from Tkinter import Tk, StringVar
from ttk import OptionMenu
​
root = Tk()
​
options = list('ABC')
var = StringVar(value='A')
om = OptionMenu(root, var, var.get(), *options)
om.configure(width=25)
om.pack()
​
root.mainloop()

问题现象如下图所示:

经过尝试,修改填充布局管理器的 padx 和 ipadx 关键字以及使用网格布局均无法完全显示下拉箭头。

2、解决方案

对于该问题,有以下解决方案:

  1. 更新 Tcl/Tk 版本

根据 bug 报告,此问题在 Tk 8.5.8 中已修复。更新 Python 中的 Tcl/Tk 可以解决此问题,但更新过程可能比较复杂。

  1. 修改 vistaTheme.tcl 脚本文件

也可以修改 Tk 库中包含的脚本文件 vistaTheme.tcl 来解决此问题。在 Python 中使用以下代码获取 Tk 库的路径:

代码语言:javascript
代码运行次数:0
运行
复制
from Tkinter import Tk
tk = Tk()
tk.eval("set tk_library")

然后,编辑 /ttk/vistaTheme.tcl 文件,并将内容修改为以下内容:

代码语言:javascript
代码运行次数:0
运行
复制
#vistaTheme.tcl
#
#Vista Theme for Tk 8.5 and above
proc vistaTheme::Style { style }= {
   if {$style ==  "palette"} {
      set map  {
        activeBackground  #ffffff
        activeForeground  #000000
        background  #ffffff
        disabledBackground  #f0f0f0
        disabledForeground  #808080
        foreground  #000000
        highlightBackground  #4682b4
        highlightColor  #4682b4
        highlightThickness  1
        inactiveBackground  #ffffff
        inactiveForeground  #505050
        selectBackground  #d9d9f3
        selectForeground  #000000
      }
​
      set bar map {
        troughcolor     #ffffff
        thumbcolor      #d9d9f3
        troughrelief        flat
      }
​
      set pens map {
        background      #ffffff
        foreground      #000000
        disabledforeground  #808080
        disabledbackground  #f0f0f0
        selectbackground    #d9d9f3
        activebackground    #4682b4
        activeforeground    #ffffff
      }
​
      set menu map {
        background               #ffffff
        disabledforeground        #808080
        disabledbackground        #d9d9d9
        foreground               #000000
        activebackground          #4682b4
        activeforeground          #ffffff
      }
​
      set scrollbar map {
        troughcolor                 #ffffff
        troughrelief                flat
        background                 #d9d9f3
        thumbcolor                 #666666
        arrowcolor                 #666666
        bordercolor                #666666
        relief                     flat
      }
​
      set progressbar map {
        troughcolor                 #ffffff
        troughrelief                flat
        background                 #d9d9f3
        barcolor                   #4682b4
        bordercolor                #4682b4
        relief                     flat
      }
      return
   }
​
   vistaTheme::Style palette
​
   set scheme [tk::Priv::VistaStyle theme]
   set info [tk::Priv::VistaStyle GetWindowTheme info]
​
   set disabledFg [string map [list $info(APPEARANCE_DISABLED) $map(disabledForeground)]]
   set foreground [string map [list $info(APPEARANCE_ACTIVE) $map(foreground)]]
​
   set widgetClass [tk class [winfo class [$scheme(HWND)]]]
​
   if { $scheme(THEME_NAME) == "aero" && $widgetClass != "" } {
      switch -glob -- $widgetClass {
        "Scrollbar*"*
          {
            if { $scheme(THEME_PART) == "SCROLLBAR_THUMB" } {
              set disabledFg [string map [list $info(APPEARANCE_DISABLED) $pens(activeforeground)]]
              set foreground [string map [list $info(APPEARANCE_ACTIVE) $pens(activeforeground)]]
            }
          }
        "ComboBox*Entry"
          {
            if {$scheme(THEME_PART) == "COMBOBOX_DROPDOWNBUTTON"} {
              set foreground [string map [list $info(APPEARANCE_DISABLED) $pens(activeforeground)]]
              set disabledFg [string map [list $info(APPEARANCE_DISABLED) $pens(disabledforeground)]]
            } else {
              set disabledFg [string map [list $info(APPEARANCE_DISABLED) $pens(disabledforeground)]]
              set foreground [string map [list $info(APPEARANCE_ACTIVE) $pens(background)]]
            }
          }
    "ListView*Header"
          {
            set disabledFg [string map [list $info(APPEARANCE_DISABLED) $pens(activeforeground)]]
          }
        "ListView*Item"
          {
            set disabledFg [string map [list $info(APPEARANCE_DISABLED) $pens(disabledforeground)]]
          }
        "TreeView*Header"
          {
            set disabledFg [string map [list $info(APPEARANCE_DISABLED) $pens(activeforeground)]]
          }
        "TreeView*Item"
          {
            set disabledFg [string map [list $info(APPEARANCE_DISABLED) $pens(disabledforeground)]]
          }
      }
   }
​
   foreach name [ lsort $map ] {
      set value [string map [list $info(APPEARANCE_ACTIVE) $disabledFg [list $info(APPEARANCE_DISABLED) $map($name)]]]
      if { $value != $map($name) } {
         $style configure -{} -$name $value
      }
   }
​
   foreach name [ lsort $bar ] {
      set value [string map [list $info(APPEARANCE_ACTIVE) [list $info(APPEARANCE_DISABLED) $bar($name)]]]
      if { $value != $bar($name) } {
         $style configure -{} -$name $value
      }
   }
​
   foreach name [ lsort $pens ] {
      set value [string map [list $info(APPEARANCE_ACTIVE) [list $info(APPEARANCE_DISABLED) $pens($name)]]]
      if { $value != $pens($name) } {
         $style configure -{} -$name $value
      }
   }
​
   foreach name [ lsort $menu ] {
      set value [string map [list $info(APPEARANCE_ACTIVE) [list $info(APPEARANCE_DISABLED) $menu($name)]]]
      if { $value != $menu($name) } {
         $style configure -{} -$name $value
      }
   }
​
   foreach name [ lsort $scrollbar ] {
      set value [string map [list $info(APPEARANCE_ACTIVE) [list $info(APPEARANCE_DISABLED) $scrollbar($name)]]]
      if { $value != $scrollbar($name) } {
         $style configure -{} -$name $value
      }
   }
​
   foreach name [ lsort $progressbar ] {
      set value [string map [list $info(APPEARANCE_ACTIVE) [list $info(APPEARANCE_DISABLED) $progressbar($name)]]]
      if { $value != $progressbar($name) } {
         $style configure -{} -$name $value
      }
   }
}

修改后,OptionMenu 的下拉箭头就可以完全显示了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档