使用 Glade3/Python3 Gtk 在运行时更改图像
Change images at runtime with Glade3/Python3 Gtk
如何使用 Glade 在运行时更改图像?
我试图在按下按钮时在我的 GUI 中提示 "refresh" 图像。我的想法是我的处理程序会对图像做一些工作,一旦完成,图像就会从文件中加载新的图像数据。
从 this post 开始我一直在努力尝试实现这一目标,但没有成功。
下面是我正在使用的精简版。每当按下按钮时,我只是想加载第二张图片。我还尝试使用图像文件路径创建一个新的 PixBuf,将其分配给图像小部件,然后将其添加回父级。
我已验证生成器正在正确检索图像。
import gi
gi.require_version('Gtk','3.0')
from gi.repository import Gtk, GdkPixbuf
STREETMAP = "/home/testrun/testing/output.png"
RADARMAP = "/home/testrun/testing/radar.png"
# The glade file to load widgets from
GLADEFILE = "slideshow.glade"
def get_builder(filename):
builder = Gtk.Builder()
builder.add_from_file(filename)
return builder
class mapWindow:
def __init__(self):
self.builder = get_builder(GLADEFILE)
self.toggle = 1
# Define signal mappings for builder
self.handlers = {
"quit" :self.quit,
"change" :self.change
}
self.window = self.builder.get_object("window1")
self.builder.connect_signals(self.handlers)
def quit(self, *args):
Gtk.main_quit(*args)
def change(self, button):
image_file = ""
if(1 == self.toggle):
self.toggle = 0
image_file = RADARMAP
else:
self.toggle = 1
image_file = STREETMAP
print("Changing image to %s" % image_file)
builder = get_builder(GLADEFILE)
mapImg = builder.get_object("image1")
parent = builder.get_object("box1")
parent.remove(mapImg)
mapImg.clear()
mapImg.set_from_file(image_file)
parent.add(mapImg)
mapImg.show()
self.window.show_all()
print("Image rendered")
myWindow = mapWindow()
myWindow.window.show_all()
Gtk.main()
这是我的 .glade 文件:
<?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>
<signal name="delete-event" handler="quit" swapped="no"/>
<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="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixbuf">radar.png</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">Change</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="pressed" handler="change" 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>
将 glade 小部件从方法 change()
移动到 __init__()
方法并让它们成为对象属性,无需总是检索相同的小部件。
一旦您将其作为 属性,然后在 change
回调方法中只需更改图像即可。请注意,如果图像大小不同,window 将在第二张图像较大时重新调整其大小,但如果较小则不会缩小。
检查哈希行之间的代码:
def __init__(self):
self.builder = get_builder(GLADEFILE)
...
#############################################################
self.window = self.builder.get_object("window1")
self.mapImg = self.builder.get_object("image1")
self.parent = self.builder.get_object("box1")
self.builder.connect_signals(self.handlers)
self.window.show_all()
#############################################################
...
...
...
def change(self, button):
image_file = ""
if(1 == self.toggle):
self.toggle = 0
image_file = RADARMAP
else:
self.toggle = 1
image_file = STREETMAP
print("Changing image to %s" % image_file)
#############################################################
self.mapImg.set_from_file(image_file)
#############################################################
print("Image rendered")
如何使用 Glade 在运行时更改图像?
我试图在按下按钮时在我的 GUI 中提示 "refresh" 图像。我的想法是我的处理程序会对图像做一些工作,一旦完成,图像就会从文件中加载新的图像数据。
从 this post 开始我一直在努力尝试实现这一目标,但没有成功。
下面是我正在使用的精简版。每当按下按钮时,我只是想加载第二张图片。我还尝试使用图像文件路径创建一个新的 PixBuf,将其分配给图像小部件,然后将其添加回父级。
我已验证生成器正在正确检索图像。
import gi
gi.require_version('Gtk','3.0')
from gi.repository import Gtk, GdkPixbuf
STREETMAP = "/home/testrun/testing/output.png"
RADARMAP = "/home/testrun/testing/radar.png"
# The glade file to load widgets from
GLADEFILE = "slideshow.glade"
def get_builder(filename):
builder = Gtk.Builder()
builder.add_from_file(filename)
return builder
class mapWindow:
def __init__(self):
self.builder = get_builder(GLADEFILE)
self.toggle = 1
# Define signal mappings for builder
self.handlers = {
"quit" :self.quit,
"change" :self.change
}
self.window = self.builder.get_object("window1")
self.builder.connect_signals(self.handlers)
def quit(self, *args):
Gtk.main_quit(*args)
def change(self, button):
image_file = ""
if(1 == self.toggle):
self.toggle = 0
image_file = RADARMAP
else:
self.toggle = 1
image_file = STREETMAP
print("Changing image to %s" % image_file)
builder = get_builder(GLADEFILE)
mapImg = builder.get_object("image1")
parent = builder.get_object("box1")
parent.remove(mapImg)
mapImg.clear()
mapImg.set_from_file(image_file)
parent.add(mapImg)
mapImg.show()
self.window.show_all()
print("Image rendered")
myWindow = mapWindow()
myWindow.window.show_all()
Gtk.main()
这是我的 .glade 文件:
<?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>
<signal name="delete-event" handler="quit" swapped="no"/>
<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="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixbuf">radar.png</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">Change</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="pressed" handler="change" 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>
将 glade 小部件从方法 change()
移动到 __init__()
方法并让它们成为对象属性,无需总是检索相同的小部件。
一旦您将其作为 属性,然后在 change
回调方法中只需更改图像即可。请注意,如果图像大小不同,window 将在第二张图像较大时重新调整其大小,但如果较小则不会缩小。
检查哈希行之间的代码:
def __init__(self):
self.builder = get_builder(GLADEFILE)
...
#############################################################
self.window = self.builder.get_object("window1")
self.mapImg = self.builder.get_object("image1")
self.parent = self.builder.get_object("box1")
self.builder.connect_signals(self.handlers)
self.window.show_all()
#############################################################
...
...
...
def change(self, button):
image_file = ""
if(1 == self.toggle):
self.toggle = 0
image_file = RADARMAP
else:
self.toggle = 1
image_file = STREETMAP
print("Changing image to %s" % image_file)
#############################################################
self.mapImg.set_from_file(image_file)
#############################################################
print("Image rendered")