林间空地Python如何关闭第二个窗口
我正在尝试使用 Glade+Python 编写带有两个窗口的简单应用程序。 请看一下我的代码。 启动文件:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from handlers import *
builder = Gtk.Builder.new_from_file("okno1.glade")
window = builder.get_object("okno") #Main window of the application
window_about = builder.get_object("okno2") #second window of the application - should not be shown at the beginning
builder.connect_signals(Handlers()) #here i connect class "Handlers" which make some actions with signals from both windows
window.connect("delete-event", Gtk.main_quit) # i connect "delete-event" with main window. If we close it, whole app should be closed - works as it should
window_about.connect("delete-event", Gtk.Window.hide) #Here is problematic line....
Gtk.main()
以及带有处理程序类的文件:
class Handlers:
def okno_button_clicked_cb(self, widget):
'''this method takes care about button on main window'''
widget.show_all()
def okno2_button_clicked_cb(self, widget):
'''this method takes care about button on second window'''
widget.hide()
左侧是主窗口。如果我单击其上的按钮,则会出现右侧的窗口。如果我单击第二个窗口上的按钮 - 它就会消失。当我再次单击主窗口上的按钮时,会出现第二个窗口 - 一切正常。但是,如果我单击第二个窗口顶部的“X”按钮,第二个窗口就会消失,如果我再次单击主窗口上的按钮,则会出现第二个窗口,但没有按钮......问题出在哪里???我认为第二个窗口(window_about)的“删除事件”有问题。但是我应该使用什么来代替 Gtk.Window.hide ???
请帮忙,我完全没有主意了:-(
PS 这里是“okno1.glade”:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.4 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="okno">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="default_width">440</property>
<property name="default_height">250</property>
<child>
<object class="GtkFixed">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="okno_button">
<property name="label" translatable="yes">otworz durgie okno</property>
<property name="width_request">100</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="okno_button_clicked_cb" object="okno2" swapped="no"/>
</object>
<packing>
<property name="x">232</property>
<property name="y">134</property>
</packing>
</child>
</object>
</child>
<child type="titlebar">
<placeholder/>
</child>
</object>
<object class="GtkWindow" id="okno2">
<property name="can_focus">False</property>
<property name="modal">True</property>
<property name="default_width">440</property>
<property name="default_height">250</property>
<child>
<object class="GtkFixed">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="okno2_button">
<property name="label" translatable="yes">zamknij okno
</property>
<property name="width_request">100</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="okno2_button_clicked_cb" object="okno2" swapped="no"/>
</object>
<packing>
<property name="x">237</property>
<property name="y">132</property>
</packing>
</child>
</object>
</child>
<child type="titlebar">
<placeholder/>
</child>
</object>
</interface>
I am trying to write simple aplication with two windows using Glade+Python.
Take look at my code please.
Start file:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from handlers import *
builder = Gtk.Builder.new_from_file("okno1.glade")
window = builder.get_object("okno") #Main window of the application
window_about = builder.get_object("okno2") #second window of the application - should not be shown at the beginning
builder.connect_signals(Handlers()) #here i connect class "Handlers" which make some actions with signals from both windows
window.connect("delete-event", Gtk.main_quit) # i connect "delete-event" with main window. If we close it, whole app should be closed - works as it should
window_about.connect("delete-event", Gtk.Window.hide) #Here is problematic line....
Gtk.main()
And file with handler class:
class Handlers:
def okno_button_clicked_cb(self, widget):
'''this method takes care about button on main window'''
widget.show_all()
def okno2_button_clicked_cb(self, widget):
'''this method takes care about button on second window'''
widget.hide()
Thare is main Window on left. If I click on the button on it, window on right appears. If I click button on second window - it dissapears. When I click again button on main window second window appears - everything works fine. But if I click "X" button on the top of second window, second window dissapear, and if I click again button on main window, second window appears but without its button.... Where is the problem???? I think something is wrong with "delete event" of second window (window_about). But what should I use instead of Gtk.Window.hide????
Please help, I am completely out of ideas :-(
P.S. here is "okno1.glade":
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.4 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="okno">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="default_width">440</property>
<property name="default_height">250</property>
<child>
<object class="GtkFixed">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="okno_button">
<property name="label" translatable="yes">otworz durgie okno</property>
<property name="width_request">100</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="okno_button_clicked_cb" object="okno2" swapped="no"/>
</object>
<packing>
<property name="x">232</property>
<property name="y">134</property>
</packing>
</child>
</object>
</child>
<child type="titlebar">
<placeholder/>
</child>
</object>
<object class="GtkWindow" id="okno2">
<property name="can_focus">False</property>
<property name="modal">True</property>
<property name="default_width">440</property>
<property name="default_height">250</property>
<child>
<object class="GtkFixed">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="okno2_button">
<property name="label" translatable="yes">zamknij okno
</property>
<property name="width_request">100</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="okno2_button_clicked_cb" object="okno2" swapped="no"/>
</object>
<packing>
<property name="x">237</property>
<property name="y">132</property>
</packing>
</child>
</object>
</child>
<child type="titlebar">
<placeholder/>
</child>
</object>
</interface>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我将解释问题及其解决方案,但如果您只想要解决方案而不需要解释,完整的解决方案代码位于答案的末尾。
问题就在这里。您可能注意到,当您单击 okno_button 时,终端会打印一条错误消息:
这意味着当 Gtk 调用您连接到
的
信号,它给它两个参数,而不是一个。在本例中,一个参数是hide()
函数时删除事件self
,因为hide()
是一种类方法。当窗口关闭(并且发送delete-event
信号)时,hide()
将获取两个参数:self
、和窗口关闭事件。此错误消息的解决方案是编写一个单独的函数,该函数确实接受两个参数。这是一个简单的示例:
但是,如果您使用此函数而不是
hide()
(window_about.connect("delete-event", hide_window)
),按钮仍然消失。这是因为 Gtk 的delete-event
删除了窗口(这并不奇怪)。为了防止窗口删除自身,您可以在
hide_window()
函数末尾返回 True
。在回调函数末尾使用 return True 告诉 Gtk 不要对事件做出反应;你已经处理好了。这是一个很好的技巧,在文本编辑器等程序员想要覆盖文本小部件的默认行为的情况下特别方便。话虽如此,这里是完整的工作代码,其中
hide_window()
函数仅在窗口关闭时隐藏;窗口没有被删除。I'll explain the problem and its solution, but if you just want the solution without the explanation, the full solution code is at the end of the answer.
Here's the problem. You probably notice that, when you click
okno_button
, the terminal prints an error message:This means that when Gtk calls the
hide()
function that you connected to thedelete-event
signal, it's giving it two arguments, instead of one. In this case, the one argument isself
, sincehide()
is a class method. When the window is closed (and thedelete-event
signal is sent),hide()
is getting two arguments:self
, and the window-close event.The solution to this error message is to write a separate function that does take two arguments. Here is a simple example:
However, if you use this function instead of
hide()
(window_about.connect("delete-event", hide_window)
), the button still disappears. This is because Gtk'sdelete-event
deletes the window (no surprise there).To prevent the window from deleting itself, you can
return True
at the end of yourhide_window()
function. Usingreturn True
at the end of a callback function tells Gtk not to react to the event; that you've already taken care of it. This is a nice trick that comes in especially handy in things like text editors, where programmers want to override the default behaviors of a text widget.All that being said, here is the full working code, with the
hide_window()
function that only hides the window when it's closed; the window isn't deleted.