【问题标题】:Refresh A Widget/Grid in GTK3 python every second每秒刷新 GTK3 python 中的小部件/网格
【发布时间】:2022-07-05 08:55:09
【问题描述】:

所以这是我的第一个 GTK3 python 应用程序,我想做的是显示我当前播放的 Spotify 歌曲的曲目艺术、歌曲名称和艺术家。

这可行,但我需要它每隔几秒刷新一次,以便应用程序切换歌曲信息。

这是我目前的代码:

import gi
import os
import subprocess
import urllib.request as ur
from PIL import Image

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, GdkPixbuf
if os.path.exists("art.png"):
    os.remove("art.png")
else:
    print("")

class Window(Gtk.Window):
    def __init__(self):
        super().__init__(title="current song playing")
        artist = subprocess.Popen("playerctl metadata artist", shell=True, stdout=subprocess.PIPE).communicate()[0]
        artist = artist.strip().decode('ascii')

        print(Gtk.events_pending())

        song   = subprocess.Popen("playerctl metadata title", shell=True, stdout=subprocess.PIPE).communicate()[0]
        song   = song.strip().decode('ascii')

        art    = subprocess.Popen("playerctl metadata mpris:artUrl", shell=True, stdout=subprocess.PIPE).communicate()[0]
        art    = art.strip().decode('ascii')

        ur.urlretrieve(art, "art.png")
        pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
        filename="art.png",
        width=200,
        height=200,
        preserve_aspect_ratio=True)
        self.image = Gtk.Image.new_from_pixbuf(pixbuf)

        self.main_box = Gtk.Box()
        self.label = Gtk.Label()
        self.label.set_markup("<big>%s - %s</big>\n" % (artist, song))
        self.label.set_justify(Gtk.Justification.CENTER)

        self.label.set_hexpand(True)
        self.image.set_hexpand(True)
        self.label.set_vexpand(True)
        self.image.set_vexpand(True)

        grid = Gtk.Grid()
        grid.add(self.image)
        grid.attach_next_to(self.label, self.image, Gtk.PositionType.BOTTOM, 1, 2)

        self.main_box.pack_start(self.image, True, True, 0)
        self.main_box.pack_start(self.label, True, True, 0)

        self.add(grid)
        self.show_all()

def main():
    win=Window()
    win.show()
    win.connect("destroy", Gtk.main_quit)
    Gtk.main()

if __name__ == "__main__":
    main()

如果尝试了不同的方法,并查看文档,都没有工作/帮助。

【问题讨论】:

    标签: python python-3.x gtk gtk3


    【解决方案1】:

    gtk4 drawing-model

    有多种方法可以驱动时钟,在最低级别您 可以使用 gdk_frame_clock_request_phase() 请求特定阶段 这将根据需要安排时钟节拍,以便最终 达到要求的阶段。然而,在实践中,大多数事情都会发生 在更高级别:

    • 如果你在做动画,你可以使用 gtk_widget_add_tick_callback() 这将导致定期跳动 在更新阶段带有回调的时钟,直到您停止 打勾。
    • 如果某些状态更改导致您的小部件的大小发生更改 您调用 gtk_widget_queue_resize() 将请求布局阶段 并将您的小部件标记为需要重新布局。
    • 如果某些状态发生变化,您需要重新绘制小部件的某些区域 您使用普通的 gtk_widget_queue_draw() 函数集。这些 将请求 Paint 阶段并将该区域标记为需要重绘。

    【讨论】:

    • 对不起,但我很确定这些函数是用于 C 的,我正在使用 python。
    【解决方案2】:

    GLib 提供timeout_add 来每 x 次运行一个任务。如果timeout_add调用的方法返回True,将在定义的超时后再次调用

    您的代码如下所示:

    import gi
    import os
    import subprocess
    import urllib.request as ur
    
    gi.require_version("Gtk", "3.0")
    from gi.repository import Gtk, GLib, GdkPixbuf
    if os.path.exists("art.png"):
        os.remove("art.png")
    
    
    class MainWindow(Gtk.Window):
    
        def __init__(self):
            super().__init__(title="current song playing")
    
            self.main_box = Gtk.Box()
            self.label = Gtk.Label()
            self.label.set_justify(Gtk.Justification.CENTER)
    
            self.image = Gtk.Image()
            self.label.set_hexpand(True)
            self.image.set_hexpand(True)
            self.label.set_vexpand(True)
            self.image.set_vexpand(True)
            self.art_url = None
    
            grid = Gtk.Grid()
            grid.add(self.image)
            grid.attach_next_to(self.label, self.image, Gtk.PositionType.BOTTOM, 1, 2)
    
            self.main_box.pack_start(self.image, True, True, 0)
            self.main_box.pack_start(self.label, True, True, 0)
    
            self.add(grid)
            self.show_all()
    
        def update_image(self):
            artist = subprocess.Popen("playerctl metadata artist", shell=True, stdout=subprocess.PIPE).communicate()[0]
            artist = artist.strip().decode('utf8')
            song   = subprocess.Popen("playerctl metadata title", shell=True, stdout=subprocess.PIPE).communicate()[0]
            song   = song.strip().decode('utf8')
            art    = subprocess.Popen("playerctl metadata mpris:artUrl", shell=True, stdout=subprocess.PIPE).communicate()[0]
            art    = art.strip().decode('utf8')
            if art and art != self.art_url:
                print("downloading %s" % art)
                self.art_url = art
                ur.urlretrieve(art, "art.png")
                pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
                    filename="art.png",
                    width=200,
                    height=200,
                    preserve_aspect_ratio=True)
                self.image.set_from_pixbuf(pixbuf)
    
            self.label.set_markup("<big>%s - %s</big>\n" % (artist, song))
            return True
    
        def start_timer(self):
            GLib.timeout_add(1000, self.update_image)
    
    
    win = MainWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()
    win.start_timer()
    Gtk.main()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 2012-12-03
      • 2012-07-25
      • 1970-01-01
      相关资源
      最近更新 更多