使用 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")