如何在 ruby 中的 TkRoot 上设置 WM_CLASS
Posted
技术标签:
【中文标题】如何在 ruby 中的 TkRoot 上设置 WM_CLASS【英文标题】:How to set WM_CLASS on TkRoot in ruby 【发布时间】:2022-01-10 08:48:28 【问题描述】:我正在尝试为我的 ruby tk 应用程序设置“WM_CLASS”属性。我尝试了几种方法,但我认为它应该是这样的:
TkRoot.new(class: 'Test')
但这会出错:
<internal:kernel>:18:in `class': wrong number of arguments (given 1, expected 0) (ArgumentError)
from /home/ben/.gem/ruby/3.0.0/gems/tk-0.4.0/lib/tk/root.rb:40:in `block in new'
from /home/ben/.gem/ruby/3.0.0/gems/tk-0.4.0/lib/tk/root.rb:36:in `each'
from /home/ben/.gem/ruby/3.0.0/gems/tk-0.4.0/lib/tk/root.rb:36:in `new'
from examples/form.rb:19:in `initialize'
from examples/form.rb:49:in `new'
from examples/form.rb:49:in `<main>'
如何正确做?
【问题讨论】:
查看 Ruby Tk 的源代码,似乎只有 Tk::Frame 和 Tk::Toplevel 可以分配一个类。我不确定这是否真的是 Tk 本身的限制,而不是 Ruby 特有的,但这是浏览源代码时的样子。 为什么要设置WM_CLASS?我在想可能还有其他方法可以完成您正在尝试做的事情。 @Casper 我正在尝试设置 WM_CLASS,因为这就是我可以使用我的窗口管理器识别窗口的方式。我会看看你说的关于 TkFrame 和 TkToplevel 的内容 在研究您的问题时,我发现 Tk 有一个group
命令可以将类似的窗口组合在一起以供窗口管理器使用。如果您正在寻找分组,那么该命令可能也值得一试。
我不确定我的答案是否真的是一个答案:-/ Ruby Tk 似乎记录得很差,并且源代码的元编码级别足够深,几乎不可能弄清楚它在做什么。可能有一种方法,我们只是想不通。也许尝试在 Github 存储库上提出问题,看看是否会得到更好的回应?
【参考方案1】:
Tk (C api) 将 WM_CLASS 值设置为 argv[0]
的值,这与 ruby 中的 $0
相同。所以要设置 WM_CLASS,必须在需要 Tk 之前设置$0
。即:
$0 = 'myWmClass'
require 'Tk'
# ... rest of the code follows here
这会将应用程序名称(WM_CLASS)设置为“myWmClass”,并将应用程序类设置为“MyWmClass”(因此此处强制使用大写)。如果想将应用程序名称设置为不同的名称,可以在需要 Tk 后通过Tk.appname('someFancyName')
完成。请注意,即使需要 Tk,主窗口似乎也没有创建,因此新创建的主窗口从一开始就具有正确的应用程序名称。另请注意,使用大写字符串作为应用程序名称可能会导致错误,如official tk command reference 所述。
对于任何其他顶层窗口(除了根窗口),可以在构造时设置 WM_CLASS,例如TkToplevel.new(root, class: 'Toplevel')
。尝试在 TkRoot 上执行此操作当前会导致异常。 (但它似乎可以在 python api 中工作。)
【讨论】:
还有一个TIP(Tcl Improvement Proposal):core.tcl-lang.org/tips/doc/trunk/tip/612.md以上是关于如何在 ruby 中的 TkRoot 上设置 WM_CLASS的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Mac OS 上使用 ruby 设置文件创建时间?
如何在Docker上设置ruby - 得到nokogiri错误
无法在 Mac 上设置 ruby-selenium Webdriver