关闭 GUI window 不会结束程序
Closing the GUI window does not end the program
我已经阅读了很多关于 Glade 的文章,并且在过去的几天里一直在使用它来获得一个基本的 Python GUI 应用程序。我能够显示 window,但每当我关闭它时,我都会在启动我的程序的终端中得到一个幻影进程 - 应用程序只是挂起,但 window 是隐藏的。该进程只能通过 kill 来终止——它不响应 Ctrl-C 或 Ctrl-D。
历险记 - 我尝试了什么
我的代码中有一个函数叫做 onDeleteWindow
对代码的所有修改都发生在这个函数内。
我查阅了各种资源,包括 this Stack Overflow question and this GTK3 documentation example,这里是我从这些资源中提取的不同方法,当然,我也尝试过:
方法一:window.connect("destroy", self.Destroy)
方法 2:self.quit
或 self.quit()
方法三:gtk.main_quit()
所有这些都会导致相同的结果——幽灵进程。如果按原样复制和粘贴,GTK3 文档中的示例也会导致相同的结果。
我的申请和代码
somegui.py:
from gi.repository import Gtk
import sys
class Handler:
def onDeleteWindow(self, *args):
self.quit()
def onButtonPressed(self, button):
print("Hello World!")
builder = Gtk.Builder()
builder.add_from_file("somegui.glade")
builder.connect_signals(Handler())
window = builder.get_object("MainWindow")
window.show_all()
builder.get_objects()
Gtk.main()
somegui.glade:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface domain="">
<requires lib="gtk+" version="3.10"/>
<object class="GtkWindow" id="MainWindow">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Hi there</property>
<property name="startup_id">MainWindow</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Hi there!</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">Awesome button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<property name="yalign">0.56000000238418579</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
Gtk 版本:(根据XML)3.10
Python version: (通过启动解释器检查) 2.7.6
我做错了什么?在过去的几天里,我一直在努力让它工作,但没有任何进展。任何提示将不胜感激。
编辑: .glade 文件似乎有问题,我已经复制并再次粘贴了它的源代码,希望这会起作用。
EDIT2: 谢谢大家花时间回答。问题是处理程序没有与 GUI 本身配对。
我无法使用 Glade 打开这个 somegui.glade
文件。应用程序报告标签过早关闭。
无论如何,您没有将信号连接到处理程序。如果您使用 Glade 来映射哪些方法将处理来自哪些小部件的哪些信号,则 connect_signals
方法将起作用。要将信号映射到方法,请使用 Glade 打开 .ui
或 .glade
文件,select 一个小部件(例如,一个按钮),然后单击下方的 "Signals" 选项卡右窗格的一部分。通常你只需要在 "handler" 列中写上方法名称,在对应于你要处理的信号的行中。
首先:您是手动编辑 XML 吗?您的 Glade 文件已损坏,因为您将 2 children 添加到 Window。那是不允许的。您需要向 window 添加一个容器(例如 GtkBox),然后将所有其他小部件放入该框内。
在您的 Python 代码中,您还调用了 self.quit()
但 self 在这种情况下只是一个 Python object。而且它没有从 GTK 继承任何方法。再看看 类 在 Python-GTK3-Tutorial (https://python-gtk-3-tutorial.readthedocs.org/en/latest/).
中是如何定义的
正如 Leonardo 提到的,您还需要在 Glade 中定义信号,然后在 Python 中使用相同的名称,以便连接处理程序。这是您需要设置 window-destroy 信号的地方:
这是我要使用的基本设置:
from gi.repository import Gtk
import sys
class Handler(object):
def __init__(self, builder):
self.builder = builder
self.window = builder.get_object("window1")
self.window.show_all()
def on_window1_destroy(self, *args):
Gtk.main_quit()
def on_button1_clicked(self, button):
print("Hello World!")
builder = Gtk.Builder()
builder.add_from_file("somegui.glade")
hdlr = Handler(builder)
builder.connect_signals(hdlr)
Gtk.main()
和 UI:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Hi there</property>
<signal name="destroy" handler="on_window1_destroy" swapped="no"/>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Hi There!</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">Awesome Button!</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_button1_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
我已经阅读了很多关于 Glade 的文章,并且在过去的几天里一直在使用它来获得一个基本的 Python GUI 应用程序。我能够显示 window,但每当我关闭它时,我都会在启动我的程序的终端中得到一个幻影进程 - 应用程序只是挂起,但 window 是隐藏的。该进程只能通过 kill 来终止——它不响应 Ctrl-C 或 Ctrl-D。
历险记 - 我尝试了什么
我的代码中有一个函数叫做 onDeleteWindow
对代码的所有修改都发生在这个函数内。
我查阅了各种资源,包括 this Stack Overflow question and this GTK3 documentation example,这里是我从这些资源中提取的不同方法,当然,我也尝试过:
方法一:window.connect("destroy", self.Destroy)
方法 2:self.quit
或 self.quit()
方法三:gtk.main_quit()
所有这些都会导致相同的结果——幽灵进程。如果按原样复制和粘贴,GTK3 文档中的示例也会导致相同的结果。
我的申请和代码
somegui.py:
from gi.repository import Gtk
import sys
class Handler:
def onDeleteWindow(self, *args):
self.quit()
def onButtonPressed(self, button):
print("Hello World!")
builder = Gtk.Builder()
builder.add_from_file("somegui.glade")
builder.connect_signals(Handler())
window = builder.get_object("MainWindow")
window.show_all()
builder.get_objects()
Gtk.main()
somegui.glade:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface domain="">
<requires lib="gtk+" version="3.10"/>
<object class="GtkWindow" id="MainWindow">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Hi there</property>
<property name="startup_id">MainWindow</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Hi there!</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">Awesome button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<property name="yalign">0.56000000238418579</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
Gtk 版本:(根据XML)3.10
Python version: (通过启动解释器检查) 2.7.6
我做错了什么?在过去的几天里,我一直在努力让它工作,但没有任何进展。任何提示将不胜感激。
编辑: .glade 文件似乎有问题,我已经复制并再次粘贴了它的源代码,希望这会起作用。
EDIT2: 谢谢大家花时间回答。问题是处理程序没有与 GUI 本身配对。
我无法使用 Glade 打开这个 somegui.glade
文件。应用程序报告标签过早关闭。
无论如何,您没有将信号连接到处理程序。如果您使用 Glade 来映射哪些方法将处理来自哪些小部件的哪些信号,则 connect_signals
方法将起作用。要将信号映射到方法,请使用 Glade 打开 .ui
或 .glade
文件,select 一个小部件(例如,一个按钮),然后单击下方的 "Signals" 选项卡右窗格的一部分。通常你只需要在 "handler" 列中写上方法名称,在对应于你要处理的信号的行中。
首先:您是手动编辑 XML 吗?您的 Glade 文件已损坏,因为您将 2 children 添加到 Window。那是不允许的。您需要向 window 添加一个容器(例如 GtkBox),然后将所有其他小部件放入该框内。
在您的 Python 代码中,您还调用了 self.quit()
但 self 在这种情况下只是一个 Python object。而且它没有从 GTK 继承任何方法。再看看 类 在 Python-GTK3-Tutorial (https://python-gtk-3-tutorial.readthedocs.org/en/latest/).
正如 Leonardo 提到的,您还需要在 Glade 中定义信号,然后在 Python 中使用相同的名称,以便连接处理程序。这是您需要设置 window-destroy 信号的地方:
这是我要使用的基本设置:
from gi.repository import Gtk
import sys
class Handler(object):
def __init__(self, builder):
self.builder = builder
self.window = builder.get_object("window1")
self.window.show_all()
def on_window1_destroy(self, *args):
Gtk.main_quit()
def on_button1_clicked(self, button):
print("Hello World!")
builder = Gtk.Builder()
builder.add_from_file("somegui.glade")
hdlr = Handler(builder)
builder.connect_signals(hdlr)
Gtk.main()
和 UI:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Hi there</property>
<signal name="destroy" handler="on_window1_destroy" swapped="no"/>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Hi There!</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">Awesome Button!</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_button1_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>