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

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

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

  1. import gi
  2. gi.require_version("Gtk", "3.0")
  3. from gi.repository import Gtk
  4. class SecondWindow(Gtk.Window):
  5. def __init__(self):
  6. super().__init__(title="Window 2")
  7. self.set_border_width(50)
  8. self.button = Gtk.Button(label="Close second window")
  9. self.button.connect("clicked", self.on_button_clicked)
  10. self.add(self.button)
  11. def on_button_clicked(self, widget):
  12. print("Window_2: button clicked")
  13. self.close()
  14. class FirstWindow(Gtk.Window):
  15. def __init__(self):
  16. super().__init__(title="MAIN --Window 1 --")
  17. self.set_border_width(100)
  18. self.button = Gtk.Button(label="Open second window")
  19. self.button.connect("clicked", self.on_button_clicked)
  20. self.add(self.button)
  21. def on_button_clicked(self, widget):
  22. print("Second window")
  23. win_2 = SecondWindow()
  24. win_2.show_all()
  25. #
  26. # Wait here !
  27. #
  28. print("After second window has been closed")
  29. win = FirstWindow()
  30. win.connect("destroy", Gtk.main_quit)
  31. win.show_all()
  32. Gtk.main()
92vpleto

92vpleto1#

使用Gtk.Dialog

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

修改SecondWindow

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

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

内容区

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

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

更改窗口管理方式

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

  1. ...
  2. win_2 = SecondWindow(self)
  3. win_2.show_all()
  4. win_2.run() # Run the dialog
  5. ...

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

  1. ...
  2. def on_button_clicked(self, widget):
  3. print("Window_2: button clicked")
  4. self.destroy() # Close the dialog
  5. ...

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

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

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

最终结果

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

  1. import gi
  2. gi.require_version("Gtk", "3.0")
  3. from gi.repository import Gtk
  4. class SecondWindow(Gtk.Dialog):
  5. def __init__(self, parent):
  6. super().__init__(parent=parent, title="Window 2")
  7. self.set_border_width(50)
  8. self.connect("delete-event", lambda *_: self.destroy())
  9. self.button = Gtk.Button(label="Close second window")
  10. self.button.connect("clicked", self.on_button_clicked)
  11. self.area = self.get_content_area()
  12. self.area.add(self.button)
  13. def on_button_clicked(self, widget):
  14. print("Window_2: button clicked")
  15. self.destroy()
  16. class FirstWindow(Gtk.Window):
  17. def __init__(self):
  18. super().__init__(title="MAIN --Window 1 --")
  19. self.set_border_width(100)
  20. self.button = Gtk.Button(label="Open second window")
  21. self.button.connect("clicked", self.on_button_clicked)
  22. self.add(self.button)
  23. def on_button_clicked(self, widget):
  24. print("Second window")
  25. win_2 = SecondWindow(self)
  26. win_2.show_all()
  27. win_2.run()
  28. print("After second window has been closed")
  29. win = FirstWindow()
  30. win.connect("destroy", Gtk.main_quit)
  31. win.show_all()
  32. Gtk.main()
展开查看全部

相关问题