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

为何GTK4中重复打开AdwDialog会报gtk_window_present断言失败错误?

解决AdwDialog关闭后无法再次打开的问题

你遇到的问题核心是Adw.Dialog调用close()后会自动销毁自身对象,第二次调用present()时,self.dialog已经不是有效的GTK窗口实例,触发了gtk_window_present的断言失败。

以下是两种可行的解决方案:

方案1:阻止对话框关闭时销毁,改为隐藏

通过连接close-request信号,覆盖默认的销毁行为,调用hide()方法隐藏对话框,这样下次可以直接重新present。

修改后的代码:

import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')

from gi.repository import Gtk, Adw

class DemoWindow(Gtk.ApplicationWindow):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.set_title("Dialog Example")
        self.set_default_size(200, 100)

        self.dialog = Adw.Dialog(title="Dialog Example", parent=self)
        # 连接close-request信号,阻止默认销毁逻辑
        self.dialog.connect("close-request", self.on_dialog_close_request)
        self.closebtn = Gtk.Button(label="Close")
        self.closebtn.connect("clicked", self.on_close_clicked)
        self.dialog.set_child(self.closebtn)
        button = Gtk.Button(label="Open Dialog")
        button.connect("clicked", self.on_button_clicked)
        self.set_child(button)

    def on_button_clicked(self, button):
        self.dialog.present(self.get_root())

    def on_close_clicked(self, button):
        # 改为调用hide()隐藏对话框,而非close()销毁
        self.dialog.hide()

    def on_dialog_close_request(self, dialog):
        # 返回True表示已处理该信号,阻止默认销毁行为
        dialog.hide()
        return True

class DemoApp(Adw.Application):
    def __init__(self):
        super().__init__(application_id="org.example.demoapp")
        self.connect("activate", self.on_activate)

    def on_activate(self, app):
        self.win = DemoWindow(application=app)
        self.win.present()

if __name__ == "__main__":
    DemoApp().run()

方案2:每次打开时重新创建对话框实例

如果不需要复用对话框的状态,每次点击按钮时重新创建Adw.Dialog实例,避免复用已销毁的对象。

修改后的代码:

import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')

from gi.repository import Gtk, Adw

class DemoWindow(Gtk.ApplicationWindow):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.set_title("Dialog Example")
        self.set_default_size(200, 100)

        button = Gtk.Button(label="Open Dialog")
        button.connect("clicked", self.on_button_clicked)
        self.set_child(button)

    def on_button_clicked(self, button):
        # 每次点击都创建新的对话框实例
        dialog = Adw.Dialog(title="Dialog Example", parent=self)
        closebtn = Gtk.Button(label="Close")
        closebtn.connect("clicked", lambda btn: dialog.close())
        dialog.set_child(closebtn)
        dialog.present(self.get_root())

class DemoApp(Adw.Application):
    def __init__(self):
        super().__init__(application_id="org.example.demoapp")
        self.connect("activate", self.on_activate)

    def on_activate(self, app):
        self.win = DemoWindow(application=app)
        self.win.present()

if __name__ == "__main__":
    DemoApp().run()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 15:18:14