GTK3 / Glib 重复一个函数

Posted

技术标签:

【中文标题】GTK3 / Glib 重复一个函数【英文标题】:GTK3 / Glib Repeating A Function 【发布时间】:2021-11-24 03:10:42 【问题描述】:

我需要在不冻结/中断 GTK3 GUI 的情况下使用 GLib 运行 Python 函数。 GLib.timeout_add(millisecond, function_name) 是不够的。我的代码需要更多控制。但是当使用以下代码时,它会发出警告并且不会每隔几秒重复该功能:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib

builder = Gtk.Builder()
builder.add_from_file('test1.ui')
window1 = builder.get_object('window1')

class Signals:
    def on_window1_destroy(self, widget):
        Gtk.main_quit()

builder.connect_signals(Signals())

def function1():
    print("1")
    global source1
    source1 = GLib.timeout_source_new(1000)
    source1.set_callback(function1)
    context1 = GLib.MainContext.default()
    source1.attach(context1)

function1()

window1.show_all()
Gtk.main()

警告:

TypeError: function1() takes 0 positional arguments but 1 was given

但以下代码可以在没有警告的情况下运行,并且功能会在每一秒内重复:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib

builder = Gtk.Builder()
builder.add_from_file('test1.ui')
window1 = builder.get_object('window1')

class Signals:
    def on_window1_destroy(self, widget):
        Gtk.main_quit()

builder.connect_signals(Signals())

def function1(var1):
    print("1")
    global source1
    source1 = GLib.timeout_source_new(1000)
    source1.set_callback(function1)
    context1 = GLib.MainContext.default()
    source1.attach(context1)

function1(1)

window1.show_all()
Gtk.main()

这是简单的 GUI 文件 (test1.ui):

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="window1">
    <property name="can-focus">False</property>
    <property name="border-width">10</property>
    <property name="default-width">200</property>
    <property name="default-height">200</property>
    <property name="icon-name">system-monitoring-center</property>
    <child>
      <placeholder/>
    </child>
  </object>
</interface>

该函数不需要 var1。在这里可以做什么? 这是文档,但我无法解决问题: GLib.Source

OS: Debian-like Linux, Python 3.9, GTK 3.24

【问题讨论】:

set_callback 此函数采用 GSourceFunc (docs.gtk.org/glib/callback.SourceFunc.html) 类型的回调函数 (docs.gtk.org/glib/method.Source.set_callback.html),它需要将 gpointer 类型的参数传递给回调函数。 应该使用什么值作为“gpointer”。我在工作示例中使用了任意值 (1)。我不懂 C/C++,也不是一个很有经验的程序员 gpointer 是一个任意值,它可以用作任何值(它 void *(意味着它可以采用任何值)在 c++ 中不确定它是如何在 python 中定义的,但它们会有类似的定义)..而不是通过 1 你可以只通过 None 【参考方案1】:

要修复此错误,只需将*args 添加到function1 的参数中:def function1(*args):

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib

builder = Gtk.Builder()
builder.add_from_file('/home/sam/programs/python/testing/SO/test1.ui')
window1 = builder.get_object('window1')

class Signals:
    def on_window1_destroy(self, widget):
        Gtk.main_quit()

builder.connect_signals(Signals())

def function1(*args): # Added *args
    print("1")
    global source1
    source1 = GLib.timeout_source_new(1000)
    source1.set_callback(function1)
    context1 = GLib.MainContext.default()
    source1.attach(context1)

function1()

window1.show_all()
Gtk.main()

* 告诉 python 将任何位置参数放入一个元组中,在本例中为 args。如果您在function1() 中使用print(args),您应该会看到类似(None,) 的内容。最好的部分是,无论是否将参数传递给 function1(),使用 *args 都有效!

【讨论】:

以上是关于GTK3 / Glib 重复一个函数的主要内容,如果未能解决你的问题,请参考以下文章

安装gtk3.0的时候,总是提示glib2.30.0被发现,ubuntu 11.10如何移除 glib2.30.0。

破坏 Glib::RefPtr 会导致 GTK 3 核心中的断言失败

GTK3 将结构传递给回调函数 - 发生异常,分段错误

Glib 对 C 函数进行单元测试

没有引用 glib 函数

为啥使用 GLib 函数?