我正在尝试使用 Gtk 和 Julia 编程语言来做一个简单的 GUI,但是,当我尝试以编程方式获取按钮以删除组合框中的活动选择时,我收到“AssertionError”。
“错误:断言错误:xor(上一个,current_task()!== g_stack)”
我不确定如何让这个简单的例子发挥作用? 有人能指出我正确的方向吗?
这是我的非功能代码:
using Gtk
# Create widgets------------------------------------
cb = GtkComboBoxText()
button = GtkButton("Remove Active")
# Create and Add choices to ComboBox ---------------
choices = ["zero", "one", "two", "three", "four"]
for choice in choices
push!(cb,choice)
end
# Function to get the selected choice (text) from the ComboBox
function getChoice()
i = get_gtk_property(cb, "active", Int)
return choices[i+1]
end
# Function that handles the ComboBox selection change---
function selection_changed(widget)
sel = getChoice()
println("We selected: $sel")
end
# Function to handle the button press------------------
function removeChoice(widget)
set_gtk_property!(cb,:active,-1)
end
# Connect the signals to the widgets -------------------
signal_connect(selection_changed, cb, "changed")
signal_connect(removeChoice, button, "clicked")
# Create window, and add widgets to it using Box Layout
win = GtkWindow("ComboBoxText Example",200,50)
vbox = GtkBox(:v)
push!(win, vbox)
push!(vbox, cb)
push!(vbox, button)
showall(win)
请注意此 Gtk.jl 手册页末尾的警告:
警告:避免在 Gtk 回调内部进行任务切换非常重要,因为这会损坏 Gtk C 堆栈。例如,使用 @async 为自己打印或排队消息。 ... 如果您仍然在某些随机方法中看到段错误由于存在递归调用glib主循环的回调(例如创建对话框)或以其他方式导致调用g_yield,请将错误代码包装在GLib中。@sigatom 。这将推迟该代码块的执行,直到它可以在正确的堆栈上运行(但否则将像正常控制流一样运行)。
当您尝试使用信号处理程序回调更改组合框的选择状态时,就会发生这种情况 - 正如手册页所调用的那样,“递归调用 glib 主循环的回调”。
在
@async
调用前面使用 Gtk.GLib.@sigatom
或 set_gtk_property!
可以避免此问题并允许代码运行。
在这种情况下,这会导致不同的错误消息,因为
removeChoice
本身会导致 selection_change
被调用,并且在那里进行的 getChoice
调用没有考虑到 get_gtk_property(cb, "active", Int)
可能返回 -1
。所以我们得到一个BoundsError
。如何解决这个问题取决于您的用例,出于演示目的,在这种情况下我只是返回nothing
:
# Function to get the selected choice (text) from the ComboBox
function getChoice()
i = get_gtk_property(cb, "active", Int)
return i >= 0 ? choices[i+1] : nothing
end
# Function that handles the ComboBox selection change---
function selection_changed(widget)
sel = getChoice()
println("We selected: $sel")
end
# Function to handle the button press------------------
function removeChoice(widget)
@async set_gtk_property!(cb,:active,-1)
end
运行此程序,当我在 GUI 中选择两个,然后“删除活动”,然后选择四个,然后再次“删除活动”时,输出是:
julia> We selected: two
We selected: nothing
We selected: four
We selected: nothing
使用Gtk4 ... 表演(获胜) 该代码有效,谢谢 Sundar