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

Perl Gtk2获取顶层窗口标识及窗口状态问题求助

问题1:处理Gtk2::Window对象,获取唯一标识

Gtk2::Window->list_toplevels返回的是Gtk2::Window对象实例,不是字符串,所以需要调用对象的方法来获取标识信息:

  • 获取窗口标题:调用get_title()方法,这是最直观的标识(前提是你给窗口设置过标题)
  • 获取系统级唯一XID:调用$win->window->get_xid()(仅在X11环境下有效,是窗口的系统唯一ID)
  • 自定义标识:可以用set_data()给窗口绑定自定义数据,后续用get_data()读取

示例代码:

my @WL = Gtk2::Window->list_toplevels;

foreach my $win (@WL) {
    # 获取窗口标题,无标题时显示默认文本
    my $title = $win->get_title || "无标题窗口";
    # 获取X11窗口ID
    my $xid = $win->window->get_xid;
    # 打印信息
    print "窗口标题: $title | 系统XID: $xid\n";
}

# 自定义标识的用法示例
$win->set_data("unique_id", "window_001");
my $custom_id = $win->get_data("unique_id");

问题2:修复回调函数的窗口状态逻辑

原代码的问题在于:

  1. 单个state $DW只能保存一个窗口实例,多个按钮调用时会覆盖之前的窗口
  2. 窗口被关闭后,$DW仍指向已销毁的对象,此时!$DW判断失效,执行present会报错

修改方案:用哈希表存储每个hostname对应的窗口,同时监听窗口销毁事件清理无效条目:

sub SM_callback {
    my ($button, $data) = @_;
    my ($DS, $hostname) = @$data;

    # 用哈希表存储不同hostname对应的窗口,state保持哈希表的持久化
    state %windows;

    # 检查窗口是否存在且有效:不存在/已销毁则重建
    if (!exists $windows{$hostname} || !$windows{$hostname}->get_window) {
        my $DW = Gtk2::Window->new('toplevel');
        $DW->set_default_size(400, 200);
        $DW->set_title($hostname);

        my $VB = Gtk2::VBox->new(0, 0);
        $DW->add($VB);

        my $TB = Gtk2::TextBuffer->new();
        $TB->set_text($hostname);

        my $TV = Gtk2::TextView->new_with_buffer($TB);

        my $SW = Gtk2::ScrolledWindow->new(undef, undef);
        $SW->add($TV);

        $VB->add($SW);

        $DW->show_all;

        # 窗口关闭时,从哈希表中移除对应条目
        $DW->signal_connect(destroy => sub {
            delete $windows{$hostname};
        });

        $windows{$hostname} = $DW;
    } else {
        # 窗口有效,前置显示
        $windows{$hostname}->present;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:34:57