python-3.x 等待第二个Gtk 3窗口关闭,阻塞第一个窗口(Pyhton、Gtk、Linux)

yvt65v4c  于 2023-10-21  发布在  Python
关注(0)|答案(1)|浏览(94)

我有一个带有按钮的主窗口,单击该按钮后会打开第二个窗口(参见下面的工作示例)。我想“阻止”第一个主窗口(例如,变灰),并等待,直到第二个已关闭(见评论“在这里等待”)。我该怎么办?
对不起,我在网上找不到任何提示,这就是我在这里问的原因。
提前感谢您的帮助。

import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

class SecondWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="Window 2")
        self.set_border_width(50)

        self.button = Gtk.Button(label="Close second window")
        self.button.connect("clicked", self.on_button_clicked)
        self.add(self.button)

    def on_button_clicked(self, widget):
        print("Window_2: button clicked")
        self.close()

class FirstWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="MAIN --Window 1 --")
        self.set_border_width(100)

        self.button = Gtk.Button(label="Open second window")
        self.button.connect("clicked", self.on_button_clicked)
        self.add(self.button)

    def on_button_clicked(self, widget):
        print("Second window")
        win_2 = SecondWindow()
        win_2.show_all()

        #
        # Wait here !
        #

        print("After second window has been closed")

win = FirstWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
92vpleto

92vpleto1#

使用Gtk.Dialog

这可以通过Gtk.Dialog来实现。幸运的是,您不需要对代码进行太多更改;这只是处理Dialog s的一些不同之处。一个完整的工作示例将在这个答案的底部。

修改SecondWindow

为了让SecondWindow类可以与Dialog一起使用,需要更改一些东西。首先,很明显,是让它继承自Gtk.Dialog而不是Gtk.Window。其次,由于Dialogs需要有一个可以“阻止”的父窗口,因此需要在SecondWindow.__init__()方法中添加一个parent参数,并在调用super().__init__()时将其传递给parent参数:

...
class SecondWindow(Gtk.Dialog): # Inherit from Dialog
    def __init__(self, parent): # Add a `parent` parameter
        super().__init__(parent=parent, title="Window 2") # Use the `parent` parameter
...

内容区

Gtk.DialogGtk.Window之间的另一个区别是,Gtk.Dialog内置了一个Gtk.Box,然后您可以将孩子放入其中。要获取这个框,您可以调用dialog.get_content_area(),然后将按钮添加到其中:

...
self.button = Gtk.Button(label="Close second window")
self.button.connect("clicked", self.on_button_clicked)
self.area = self.get_content_area() # Get the dialog's content area
self.area.add(self.button) # Add the button to the content area
...

更改窗口管理方式

最后,当使用Dialog时,您需要修改打开和关闭辅助窗口的方式。
为了正确地打开Dialog,您需要在调用show_all()之后调用它的run()方法。run()方法确保Dialog阻止其父窗口,直到它被关闭:

...
win_2 = SecondWindow(self)
win_2.show_all()
win_2.run() # Run the dialog
...

为了正确地关闭对话框,你可以调用destroy()而不是close()close()不会立即关闭对话框):

...
def on_button_clicked(self, widget):
    print("Window_2: button clicked")
    self.destroy() # Close the dialog
...

此外,为了让对话框角落的X按钮正常工作,需要将destroy()方法连接到"delete-event"信号:

...
self.set_border_width(50)
self.connect("delete-event", lambda *_: self.destroy())
...

lambda *_用于捕获事件可能传递给destroy()的任何参数。

最终结果

下面是一个完整的工作修改您的代码,利用上述更改:

import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

class SecondWindow(Gtk.Dialog):
    def __init__(self, parent):
        super().__init__(parent=parent, title="Window 2")
        self.set_border_width(50)
        self.connect("delete-event", lambda *_: self.destroy())

        self.button = Gtk.Button(label="Close second window")
        self.button.connect("clicked", self.on_button_clicked)
        self.area = self.get_content_area()
        self.area.add(self.button)

    def on_button_clicked(self, widget):
        print("Window_2: button clicked")
        self.destroy()

class FirstWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="MAIN --Window 1 --")
        self.set_border_width(100)

        self.button = Gtk.Button(label="Open second window")
        self.button.connect("clicked", self.on_button_clicked)
        self.add(self.button)

    def on_button_clicked(self, widget):
        print("Second window")
        win_2 = SecondWindow(self)
        win_2.show_all()
        win_2.run()

        print("After second window has been closed")

win = FirstWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

相关问题