如何在 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

如何设置 webrick 服务器以使用 ruby​​ 1.9.3?

如何隔离 Ruby 中的方法 - 多处理问题

如何使用 docker(ruby on rails)设置 anycable?