首页 > 解决方案 > Julia + GTK - 回调中的全局变量更改

问题描述

我正在尝试学习 Julia 语言,而我目前的项目是一个“连续 5 个”程序。我开始为这款游戏在 Gtk 上使用 Julia wrapper 制作接口,但偶然发现了一个有趣的问题。代码如下。

问题是:回调函数工作后 cur_step 变量没有改变,按钮的标签也没有改变。但是,如果我删除回调函数中的 if 条件,则按钮在按下后都会得到标签“x”,因为它现在应该是。

我正在 Jupyter Notebook 中使用 Julia 1.0 编写我的代码。

我试图将 cur_step 变量设置为全局变量,因为我认为这是一个范围问题,但没有成功。

using Gtk

cur_step = "x"

function click_once_callback(widget)
    set_gtk_property!(widget, :sensitive, false)
    set_gtk_property!(widget, :label, cur_step)
    if cur_step == "x"
        cur_step = "o"
    else
        cur_step = "x"
    end
end

letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o']

win = GtkWindow("GoMoku")
g = GtkGrid()

buttons = []

for i=1:15
    b = []
    for j=1:15
        letter = letters[i]
        push!(b,GtkButton("$letter:$j"))
    end
    push!(buttons,b)
end

for i=1:15
    for j=1:15
        g[i,16-j] = buttons[i][j]
        id = signal_connect(click_once_callback, buttons[i][j], "clicked")
    end
end


set_gtk_property!(g, :column_homogeneous, true)
set_gtk_property!(g, :column_spacing, 15)  # introduce a 15-pixel gap between columns
set_gtk_property!(g, :row_spacing, 15)  # introduce a 15-pixel gap between rows
push!(win, g)
showall(win)

为什么全局变量不会通过回调函数改变?我希望在单击每个按钮后迭代地更改 cur_step。先感谢您!

标签: gtkjulia

解决方案


您需要将 cur_step 标记为函数内部的全局(以及外部,以获得良好的代码路标)。

只要在函数范围内的任何地方都没有赋值,函数就可以毫无问题地使用其父范围内的变量。如果某处有赋值(即使它在 if 块中),则该函数被解释为本地;即使在分配发生之前也是如此。

为了将在函数内部某个点正确分配的变量视为全局变量,您需要在函数内部使用global cur_step.


推荐阅读