Qt: How to use custom events

Created on 17 Apr 2019  路  3Comments  路  Source: therecipe/qt

I am setting a up a widget that I wish to control via a go subroutine. (I wish to change the components loaded into widget)

Since I can't change anything except on the main UI thread I figured I would use customEvents which I will emit from my subroutine, and then trigger the changes on the main thread.

I am currently stuck with composing the custom events as I can't find any examples how to do that, and I am not that familiar with what is going on here to figure it out all on my own.

Any assistance would be greatly appreciated.

Thank you for creating and maintaining this amazing project.

Most helpful comment

Hey

Yeah, using signals/slots is the more convenient option.
The problem is that you can't subclass core.QEvent that easily atm, take a look at https://github.com/therecipe/qt/issues/762 for more details.

However here is how you can make custom events work, with the help of some internal functions:

package main

import (
    "os"
    "time"

    "github.com/therecipe/qt"

    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/widgets"
)

const CustomEventID = core.QEvent__User + 1

type CustomEvent struct {
    *core.QEvent
    someProperty string
}

func main() {
    app := widgets.NewQApplication(len(os.Args), os.Args)

    //setup receiver and handler
    window := widgets.NewQMainWindow(nil, 0)
    window.ConnectEvent(func(event *core.QEvent) bool { //or ConnectCustomEvent
        if event.Type() == CustomEventID {
            defer qt.Unregister(event.Pointer())
            cEventI, _ := qt.Receive(event.Pointer())

            println("myCustomEvent:", cEventI.(*CustomEvent).someProperty)
            return true
        }
        return window.EventDefault(event)
    })
    window.Show()

    //post event
    go func() {
        time.Sleep(3 * time.Second)

        event := &CustomEvent{core.NewQEvent(CustomEventID), "hello world"}
        qt.Register(event.Pointer(), event)
        app.PostEvent(window, event, int(core.Qt__NormalEventPriority))
    }()

    app.Exec()
}

In the future something like this should be possible, but I haven't had time to look into this yet.

package main

import (
    "os"
    "time"

    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/widgets"
)

const CustomEventID = core.QEvent__User + 1

type CustomEvent struct {
    core.QEvent  `moc`
    someProperty string
}

func main() {
    app := widgets.NewQApplication(len(os.Args), os.Args)

    //setup receiver and handler
    window := widgets.NewQMainWindow(nil, 0)
    window.ConnectEvent(func(event *core.QEvent) bool { //or ConnectCustomEvent
        if event.Type() == CustomEventID {
            println("myCustomEvent:", NewCustomEventFromPointer(event.Pointer()).someProperty)
            return true
        }
        return window.EventDefault(event)
    })
    window.Show()

    //post event
    go func() {
        time.Sleep(3 * time.Second)

        event := NewCustomEvent(CustomEventID)
        event.someProperty = "hello world"
        app.PostEvent(window, event, int(core.Qt__NormalEventPriority))
    }()

    app.Exec()
}

All 3 comments

I see that I should probably be using Signals and Slots here. I would still find it interesting getting to see how custom events can be triggered manually and then having the appropriate handler complete the desired action.

Hey

Yeah, using signals/slots is the more convenient option.
The problem is that you can't subclass core.QEvent that easily atm, take a look at https://github.com/therecipe/qt/issues/762 for more details.

However here is how you can make custom events work, with the help of some internal functions:

package main

import (
    "os"
    "time"

    "github.com/therecipe/qt"

    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/widgets"
)

const CustomEventID = core.QEvent__User + 1

type CustomEvent struct {
    *core.QEvent
    someProperty string
}

func main() {
    app := widgets.NewQApplication(len(os.Args), os.Args)

    //setup receiver and handler
    window := widgets.NewQMainWindow(nil, 0)
    window.ConnectEvent(func(event *core.QEvent) bool { //or ConnectCustomEvent
        if event.Type() == CustomEventID {
            defer qt.Unregister(event.Pointer())
            cEventI, _ := qt.Receive(event.Pointer())

            println("myCustomEvent:", cEventI.(*CustomEvent).someProperty)
            return true
        }
        return window.EventDefault(event)
    })
    window.Show()

    //post event
    go func() {
        time.Sleep(3 * time.Second)

        event := &CustomEvent{core.NewQEvent(CustomEventID), "hello world"}
        qt.Register(event.Pointer(), event)
        app.PostEvent(window, event, int(core.Qt__NormalEventPriority))
    }()

    app.Exec()
}

In the future something like this should be possible, but I haven't had time to look into this yet.

package main

import (
    "os"
    "time"

    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/widgets"
)

const CustomEventID = core.QEvent__User + 1

type CustomEvent struct {
    core.QEvent  `moc`
    someProperty string
}

func main() {
    app := widgets.NewQApplication(len(os.Args), os.Args)

    //setup receiver and handler
    window := widgets.NewQMainWindow(nil, 0)
    window.ConnectEvent(func(event *core.QEvent) bool { //or ConnectCustomEvent
        if event.Type() == CustomEventID {
            println("myCustomEvent:", NewCustomEventFromPointer(event.Pointer()).someProperty)
            return true
        }
        return window.EventDefault(event)
    })
    window.Show()

    //post event
    go func() {
        time.Sleep(3 * time.Second)

        event := NewCustomEvent(CustomEventID)
        event.someProperty = "hello world"
        app.PostEvent(window, event, int(core.Qt__NormalEventPriority))
    }()

    app.Exec()
}

Thank you SO much for this <3 :-)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fabstu picture fabstu  路  4Comments

quantonganh picture quantonganh  路  6Comments

joeblew99 picture joeblew99  路  7Comments

StarAurryon picture StarAurryon  路  5Comments

iMaxopoly picture iMaxopoly  路  3Comments