Python GTK4: CheckButton 'toggled' 信号调用了数十次
Python GTK4: CheckButton 'toggled' signal called dozens of times
运行 我想向其添加 GTK 设置菜单的 Python 程序。以下功能可根据需要运行,但存在一些问题。这是相关代码:
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk
def gtk_on_activate(app):
win = Gtk.ApplicationWindow(application=app)
win.set_title('Settings')
win.set_default_size(320,240)
box = Gtk.ListBox()
for k,v in config['Settings'].items():
btn = Gtk.CheckButton(label=k,active=bool(int(v)))
btn.connect('toggled', gtk_toggled)
box.append(btn)
win.set_child(box)
win.present()
def gtk_toggled(btn):
global config
print('hi')
btn.set_active(not btn.get_active())
config.set('Subscriptions', btn.get_label(), str(int(btn.get_active())))
with open(os.path.join(os.path.dirname(__file__), 'Config/SavedVariables.cfg'), 'w') as cfg:
config.write(cfg)
app = Gtk.Application(application_id='org.gdi.Settings')
app.connect('activate', gtk_on_activate)
app.run()
这是输出:
[...]
hi
hi
hi
hi
hi
hi
hi
hi
hi
hi
hi
hi
Traceback (most recent call last):
RecursionError: maximum recursion depth exceeded while calling a Python object
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/xyz/.local/bin/scripts/Settings/Settings.py", line 95, in gtk_toggled
with open(os.path.join(os.path.dirname(__file__), 'Config/SavedVariables.cfg'), 'w') as cfg:
RecursionError: maximum recursion depth exceeded while calling a Python object
我想 RecursionError
是关于该文件可能被打开了数十次。但是我不明白:
- 为什么代码需要
print('hi')
才能工作(其他字符串工作)?
- 为什么信号发送了几十、几十次?
- 我是不是做错了什么?
感谢您的所有帮助!
编辑:我已将 open
移出该函数,并解决了 RecursionError
。我现在也尝试使用 Gtk3,并注意到相同的信号模式被发送垃圾邮件。所以我想这很正常? Gtk3 似乎已经解决了 print('hi')
作为一个奇怪的要求。我注意到 Gtk4,这个奇怪的技巧只有在程序是来自终端的 运行 时才有效。不太明白那里发生了什么......也许我应该提交错误报告?
我已经更改了代码,以便它可以与 Gtk 3 一起使用(并且没有与 config
相关的错误消息),而且问题似乎归结为 btn.set_active(not btn.get_active())
行.这是我使用的代码:
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
def gtk_on_activate(app):
win = Gtk.ApplicationWindow(application=app)
win.set_title('Settings')
win.set_default_size(320,240)
box = Gtk.ListBox()
for k,v in {"Button1": "1", "Button2": "0", "Button3": "1"}.items():
btn = Gtk.CheckButton(label=k,active=bool(int(v)))
btn.connect('toggled', gtk_toggled)
box.insert(btn, 0)
win.add(box)
win.show_all()
win.present()
def gtk_toggled(btn):
print('hi')
btn.set_active(not btn.get_active()) # This line is causing the error message
app = Gtk.Application(application_id='org.gdi.Settings')
app.connect('activate', gtk_on_activate)
app.run()
要解决此问题,只需删除 btn.set_active(not btn.get_active())
。它完全没用,因为复选按钮会自动自行更改其状态。如果您不希望用户能够更改复选按钮的状态,只需对您想要禁用的任何复选按钮使用 btn.set_sensitive(False)
。
因此,回答您的问题:
print('hi')
不是 代码工作所必需的;无论您 print('hi')
与否(至少在 Gtk 3 中),代码都会失败。
- 信号被发送了很多次,因为
btn.set_active(not btn.get_active())
行中的 btn.set_active()
函数发送 toggled
信号,然后调用 gtk_toggled()
,后者调用 btn.set_active()
,发送 toggled
信号,调用 gtk_toggled()
,然后调用 btn.set_active()
,不断调用,直到达到最大递归深度。
- 是的,你做错了什么。幸运的是,这只是最简单和最容易修复的错误,修复实际上是 less 代码和复杂化;你可以让 Gtk 为你做这些工作!
不,谢天谢地这不正常,不,你不需要提交错误报告。
运行 我想向其添加 GTK 设置菜单的 Python 程序。以下功能可根据需要运行,但存在一些问题。这是相关代码:
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk
def gtk_on_activate(app):
win = Gtk.ApplicationWindow(application=app)
win.set_title('Settings')
win.set_default_size(320,240)
box = Gtk.ListBox()
for k,v in config['Settings'].items():
btn = Gtk.CheckButton(label=k,active=bool(int(v)))
btn.connect('toggled', gtk_toggled)
box.append(btn)
win.set_child(box)
win.present()
def gtk_toggled(btn):
global config
print('hi')
btn.set_active(not btn.get_active())
config.set('Subscriptions', btn.get_label(), str(int(btn.get_active())))
with open(os.path.join(os.path.dirname(__file__), 'Config/SavedVariables.cfg'), 'w') as cfg:
config.write(cfg)
app = Gtk.Application(application_id='org.gdi.Settings')
app.connect('activate', gtk_on_activate)
app.run()
这是输出:
[...]
hi
hi
hi
hi
hi
hi
hi
hi
hi
hi
hi
hi
Traceback (most recent call last):
RecursionError: maximum recursion depth exceeded while calling a Python object
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/xyz/.local/bin/scripts/Settings/Settings.py", line 95, in gtk_toggled
with open(os.path.join(os.path.dirname(__file__), 'Config/SavedVariables.cfg'), 'w') as cfg:
RecursionError: maximum recursion depth exceeded while calling a Python object
我想 RecursionError
是关于该文件可能被打开了数十次。但是我不明白:
- 为什么代码需要
print('hi')
才能工作(其他字符串工作)? - 为什么信号发送了几十、几十次?
- 我是不是做错了什么?
感谢您的所有帮助!
编辑:我已将 open
移出该函数,并解决了 RecursionError
。我现在也尝试使用 Gtk3,并注意到相同的信号模式被发送垃圾邮件。所以我想这很正常? Gtk3 似乎已经解决了 print('hi')
作为一个奇怪的要求。我注意到 Gtk4,这个奇怪的技巧只有在程序是来自终端的 运行 时才有效。不太明白那里发生了什么......也许我应该提交错误报告?
我已经更改了代码,以便它可以与 Gtk 3 一起使用(并且没有与 config
相关的错误消息),而且问题似乎归结为 btn.set_active(not btn.get_active())
行.这是我使用的代码:
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
def gtk_on_activate(app):
win = Gtk.ApplicationWindow(application=app)
win.set_title('Settings')
win.set_default_size(320,240)
box = Gtk.ListBox()
for k,v in {"Button1": "1", "Button2": "0", "Button3": "1"}.items():
btn = Gtk.CheckButton(label=k,active=bool(int(v)))
btn.connect('toggled', gtk_toggled)
box.insert(btn, 0)
win.add(box)
win.show_all()
win.present()
def gtk_toggled(btn):
print('hi')
btn.set_active(not btn.get_active()) # This line is causing the error message
app = Gtk.Application(application_id='org.gdi.Settings')
app.connect('activate', gtk_on_activate)
app.run()
要解决此问题,只需删除 btn.set_active(not btn.get_active())
。它完全没用,因为复选按钮会自动自行更改其状态。如果您不希望用户能够更改复选按钮的状态,只需对您想要禁用的任何复选按钮使用 btn.set_sensitive(False)
。
因此,回答您的问题:
print('hi')
不是 代码工作所必需的;无论您print('hi')
与否(至少在 Gtk 3 中),代码都会失败。- 信号被发送了很多次,因为
btn.set_active(not btn.get_active())
行中的btn.set_active()
函数发送toggled
信号,然后调用gtk_toggled()
,后者调用btn.set_active()
,发送toggled
信号,调用gtk_toggled()
,然后调用btn.set_active()
,不断调用,直到达到最大递归深度。 - 是的,你做错了什么。幸运的是,这只是最简单和最容易修复的错误,修复实际上是 less 代码和复杂化;你可以让 Gtk 为你做这些工作!
不,谢天谢地这不正常,不,你不需要提交错误报告。