如何在 ruby 的 TkRoot 上设置 WM_CLASS

How to set WM_CLASS on TkRoot in ruby

我正在尝试为我的 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>'

如何正确操作?

Tk (C api) 将 WM_CLASS 值设置为 argv[0] 的值,这与 ruby 中的 [=12=] 相同。所以要设置 WM_CLASS,必须在要求 Tk 之前设置 [=12=]。即:

[=10=] = 'myWmClass'
require 'Tk'

# ... rest of the code follows here

这会将 WM_CLASS 的应用程序名称设置为 'myWmClass',并将应用程序 class 设置为 'MyWmClass'(因此此处强制使用大写)。如果想将应用程序名称设置为不同的名称,可以在需要 Tk 后通过 Tk.appname('someFancyName') 来完成。请注意,即使需要 Tk,main window 似乎并未创建,因此新创建的 main window 从一开始就具有正确的应用程序名称。另请注意,使用大写字符串作为应用程序名称可能会导致错误,如 official tk command reference 所述。

对于任何其他顶层 window(除了根 window),WM_CLASS 可以在构造时设置,e.i。 TkToplevel.new(root, class: 'Toplevel')。尝试在 TkRoot 上这样做目前会导致异常。 (不过它似乎在 python api 中有效。)