Golang中的位掩码问题,还是GoGTK3的问题?

Golang中的位掩码问题,还是GoGTK3的问题? 我正在尝试在使用 key-press-event 的 GTK 应用程序中检测控制键何时被按下。这个页面似乎大致展示了如何做到这一点(使用 C 语言):

https://developer.gnome.org/gtk3/stable/checklist-modifiers.html

这是我目前拥有的代码,但它不起作用。我开始怀疑我在第 5 行(keyEvent.KeyVal() & modifiers)进行位掩码操作的方式不正确。在 Go 中是这样进行位掩码操作的吗?或者可能是我没有正确理解 C 代码……

	// Connect to the key press event
	win.Connect("key-press-event", func(window *gtk.Window, event *gdk.Event) {
		keyEvent := gdk.EventKey{Event: event}
		modifiers := uint(gtk.AcceleratorGetDefaultModMask())
		isControlPressed := (keyEvent.KeyVal()&modifiers == gdk.GDK_CONTROL_MASK)
		if isControlPressed {
			fmt.Printf("Control is pressed")
		}
	})

更多关于Golang中的位掩码问题,还是GoGTK3的问题?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我仍然不知道应该如何操作,但我知道这一行代码存在严重问题:

modifiers := uint(gtk.AcceleratorGetDefaultModMask())

它导致了其他非常奇怪的问题(https://github.com/gotk3/gotk3/issues/542)。

因此我现在要关闭这个问题,因为它似乎与 Go 和位掩码无关。这很可能是一个 gogtk3 的问题,或者更可能是我使用方式有误。

更多关于Golang中的位掩码问题,还是GoGTK3的问题?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


从代码来看,问题确实出在位掩码操作上。在Go中,位掩码检查应该使用按位与操作来检测特定标志位是否被设置,但你的代码有几个关键问题:

  1. keyEvent.KeyVal() 返回的是按键值,而不是修饰键状态
  2. 应该使用 keyEvent.State() 来获取修饰键状态
  3. 位掩码检查应该是 state & mask != 0

以下是修正后的代码:

// Connect to the key press event
win.Connect("key-press-event", func(window *gtk.Window, event *gdk.Event) {
    keyEvent := gdk.EventKey{Event: event}
    
    // 获取当前修饰键状态
    state := keyEvent.State()
    
    // 检查Control键是否被按下
    isControlPressed := state & gdk.GDK_CONTROL_MASK != 0
    
    if isControlPressed {
        fmt.Printf("Control is pressed (key value: %v)\n", keyEvent.KeyVal())
    }
})

如果你需要同时检查多个修饰键,可以这样操作:

// 检查Control+Shift组合
isCtrlShift := (state & (gdk.GDK_CONTROL_MASK | gdk.GDK_SHIFT_MASK)) == 
               (gdk.GDK_CONTROL_MASK | gdk.GDK_SHIFT_MASK)

// 检查Control或Shift中的任意一个
isCtrlOrShift := state & (gdk.GDK_CONTROL_MASK | gdk.GDK_SHIFT_MASK) != 0

对于更复杂的修饰键处理,可以使用辅助函数:

func hasModifier(state gdk.ModifierType, mask gdk.ModifierType) bool {
    return state & mask != 0
}

// 使用示例
if hasModifier(state, gdk.GDK_CONTROL_MASK) {
    fmt.Println("Control key is pressed")
}

主要问题是混淆了KeyVal()(返回按下的具体键值,如’a’、'b’等)和State()(返回修饰键状态位掩码)的用途。位掩码操作在Go中的语法与C类似,但需要确保操作的是正确的值。

回到顶部