关闭 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)
方法 2self.quitself.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>