在 Python GTK (Glade) 中分别关闭两个 windows
Close separately two windows in Python GTK (Glade)
我最近开始使用 Python GTK 和 Glade 开发一些简单的 GUI。我创建了一个 GUI,它由一个带按钮的主 window 组成,而按下按钮的动作是第二个 window 的弹出窗口,上面有一个 matplotlib 图。
我面临的问题是,当我关闭第二个 window 时,第一个也会关闭,我希望能够分别终止它们。
下面是 python 代码,here 是带有 GUI 布局的空地文件。
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import numpy as np
from matplotlib.figure import Figure
from matplotlib.axes import Subplot
from matplotlib.backends.backend_gtk3agg import (
FigureCanvasGTK3Agg as FigureCanvas)
class PlotApp:
def __init__(self):
gladefile = 'GTK-two-windows.glade'
self.builder = Gtk.Builder()
self.builder.add_from_file(gladefile)
main_win = self.builder.get_object("window1")
main_win.connect("delete-event", Gtk.main_quit)
button = self.builder.get_object('button')
button.connect('clicked', self.plot)
main_win.show_all()
def plot(self, widget):
window2 = self.builder.get_object("window2")
window2.connect("delete-event", Gtk.main_quit)
scrolledwindow = self.builder.get_object("scrolledwindow")
# ----- Start of Matplotlib specific code -----
figure = Figure(figsize=(8, 6), dpi=71)
axis = figure.add_subplot(111)
t = np.arange(0.0, 3.0, 0.01)
s = np.sin(2*np.pi*t)
axis.plot(t, s)
axis.set_xlabel('time [s]')
axis.set_ylabel('voltage [V]')
canvas = FigureCanvas(figure) # a Gtk.DrawingArea
canvas.set_size_request(800, 600)
scrolledwindow.add_with_viewport(canvas)
# ----- End of Matplotlib specific code -----
window2.show_all()
if __name__ == "__main__":
main = PlotApp()
Gtk.main()
导入来自vext.gi、numpy和matplotlibpython包,我使用的Glade版本是3.22.1,我的OS 是初级 Linux 5.1 赫拉。
您需要更改呼叫:
.connect("delete-event", Gtk.main_quit)
以便他们仅在这是最后一次打开时才调用 Gtk.main_quit
window。
将对 Gtk.main_quit
的直接调用替换为:
def exit(window, event):
if not any(w.get_visible() for w in Gtk.Window.list_toplevels() if w is not window):
Gtk.main_quit()
这使得关闭 window 只会在它是最后一个可见的 window 时退出应用程序。
如果你只做:
window.hide()
return True
在您的销毁事件处理程序中,您永远不会关闭应用程序。
将我不认为是问题的内容结合起来,因为我无法 运行 你的程序与我建议的代码会导致 main_quit
在所有 [=31] 时被调用=] 已关闭。
经过一些研究 () 和一些实验后,我得出结论,不应关闭由我的主 window 按钮触发的第二个弹出窗口 window使用事件函数 Gtk.main_quit(),但应该使用事件函数 hide() 隐藏它。因此,第一个主要 window 将保持打开状态。
但是,由于 matplotlib 图是绘制在 FigureCanvas 上的,它包含在我的第二个弹出窗口 window 的子窗口小部件(滚动条 window)中,因此需要删除事件popup-window 销毁滚动条 window 以便能够重新绘制并避免有关现有子部件的错误。
所以在我原来问题的代码中进行以下修改添加所需的功能:
[1] 从 glade 文件中删除滚动条 window 小部件
[2] 在弹出窗口顶部添加滚动条 window window:
scrolledwindow = Gtk.ScrolledWindow()
#----- Start of Matplotlib specific code -----
figure = Figure(figsize=(8, 6), dpi=71)
axis = figure.add_subplot(111)
t = np.arange(0.0, 3.0, 0.01)
s = np.sin(2*np.pi*t)
axis.plot(t, s)
axis.set_xlabel('time [s]')
axis.set_ylabel('voltage [V]')
canvas = FigureCanvas(figure) # a Gtk.DrawingArea
canvas.set_size_request(800, 600)
scrolledwindow.add_with_viewport(canvas)
#scrolledwindow.add(canvas)
# ----- End of Matplotlib specific code -----
window2.add(scrolledwindow)
window2.show_all()
[3]更改popup的事件函数window:
window2.connect("delete-event", self.destroy)
销毁函数定义为:
def destroy(self, widget, event):
scrolledwindow = widget.get_child()
scrolledwindow.destroy()
widget.hide()
return True
然后无论我关闭第二个 window 多少次并按下主 window 中的按钮,情节都绘制在(隐藏的)第二个 window 上。
我最近开始使用 Python GTK 和 Glade 开发一些简单的 GUI。我创建了一个 GUI,它由一个带按钮的主 window 组成,而按下按钮的动作是第二个 window 的弹出窗口,上面有一个 matplotlib 图。
我面临的问题是,当我关闭第二个 window 时,第一个也会关闭,我希望能够分别终止它们。
下面是 python 代码,here 是带有 GUI 布局的空地文件。
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import numpy as np
from matplotlib.figure import Figure
from matplotlib.axes import Subplot
from matplotlib.backends.backend_gtk3agg import (
FigureCanvasGTK3Agg as FigureCanvas)
class PlotApp:
def __init__(self):
gladefile = 'GTK-two-windows.glade'
self.builder = Gtk.Builder()
self.builder.add_from_file(gladefile)
main_win = self.builder.get_object("window1")
main_win.connect("delete-event", Gtk.main_quit)
button = self.builder.get_object('button')
button.connect('clicked', self.plot)
main_win.show_all()
def plot(self, widget):
window2 = self.builder.get_object("window2")
window2.connect("delete-event", Gtk.main_quit)
scrolledwindow = self.builder.get_object("scrolledwindow")
# ----- Start of Matplotlib specific code -----
figure = Figure(figsize=(8, 6), dpi=71)
axis = figure.add_subplot(111)
t = np.arange(0.0, 3.0, 0.01)
s = np.sin(2*np.pi*t)
axis.plot(t, s)
axis.set_xlabel('time [s]')
axis.set_ylabel('voltage [V]')
canvas = FigureCanvas(figure) # a Gtk.DrawingArea
canvas.set_size_request(800, 600)
scrolledwindow.add_with_viewport(canvas)
# ----- End of Matplotlib specific code -----
window2.show_all()
if __name__ == "__main__":
main = PlotApp()
Gtk.main()
导入来自vext.gi、numpy和matplotlibpython包,我使用的Glade版本是3.22.1,我的OS 是初级 Linux 5.1 赫拉。
您需要更改呼叫:
.connect("delete-event", Gtk.main_quit)
以便他们仅在这是最后一次打开时才调用 Gtk.main_quit
window。
将对 Gtk.main_quit
的直接调用替换为:
def exit(window, event):
if not any(w.get_visible() for w in Gtk.Window.list_toplevels() if w is not window):
Gtk.main_quit()
这使得关闭 window 只会在它是最后一个可见的 window 时退出应用程序。
如果你只做:
window.hide()
return True
在您的销毁事件处理程序中,您永远不会关闭应用程序。
将我不认为是问题的内容结合起来,因为我无法 运行 你的程序与我建议的代码会导致 main_quit
在所有 [=31] 时被调用=] 已关闭。
经过一些研究 (
但是,由于 matplotlib 图是绘制在 FigureCanvas 上的,它包含在我的第二个弹出窗口 window 的子窗口小部件(滚动条 window)中,因此需要删除事件popup-window 销毁滚动条 window 以便能够重新绘制并避免有关现有子部件的错误。
所以在我原来问题的代码中进行以下修改添加所需的功能:
[1] 从 glade 文件中删除滚动条 window 小部件
[2] 在弹出窗口顶部添加滚动条 window window:
scrolledwindow = Gtk.ScrolledWindow()
#----- Start of Matplotlib specific code -----
figure = Figure(figsize=(8, 6), dpi=71)
axis = figure.add_subplot(111)
t = np.arange(0.0, 3.0, 0.01)
s = np.sin(2*np.pi*t)
axis.plot(t, s)
axis.set_xlabel('time [s]')
axis.set_ylabel('voltage [V]')
canvas = FigureCanvas(figure) # a Gtk.DrawingArea
canvas.set_size_request(800, 600)
scrolledwindow.add_with_viewport(canvas)
#scrolledwindow.add(canvas)
# ----- End of Matplotlib specific code -----
window2.add(scrolledwindow)
window2.show_all()
[3]更改popup的事件函数window:
window2.connect("delete-event", self.destroy)
销毁函数定义为:
def destroy(self, widget, event):
scrolledwindow = widget.get_child()
scrolledwindow.destroy()
widget.hide()
return True
然后无论我关闭第二个 window 多少次并按下主 window 中的按钮,情节都绘制在(隐藏的)第二个 window 上。