Qt: Best practice for background jobs

Created on 19 Apr 2019  路  1Comment  路  Source: therecipe/qt

Some actions like button presses do an HTTP call to my server and those actions block the UI, making it unresponsive.

Of course I could do it in a goroutine and and wait for it in another and push the response back to the UI but that seems to be lot of hassle. Also sometimes I get thread related errors on QT side.

What would be the best way to these kind of background tasks without blocking the UI? Are there any examples you can share?

Thanks

Most helpful comment

Hey

You can simply run anything that would block the UI in a go routine and then use signals/slots or the helper function from https://github.com/therecipe/qt/issues/841#issuecomment-485217753 to update the UI.

Something like this should work

package main

import (
    "os"
    "time"

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

type mainThreadHelper struct {
    core.QObject

    _ func(f func()) `signal:"runOnMain,auto`
}

func (*mainThreadHelper) runOnMain(f func()) { f() }

var MainThreadRunner = NewMainThreadHelper(nil)

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

    window := widgets.NewQMainWindow(nil, 0)

    button := widgets.NewQPushButton2("click me", nil)
    button.ConnectClicked(func(bool) {
        go func() {
            time.Sleep(3 * time.Second) //do something that would block the UI in go routines

            MainThreadRunner.RunOnMain(func() {
                //again on the main thread, do the UI update
                //but don't do anything that would block the UI here
                widgets.QMessageBox_Information(nil, "OK", "Hello from main thread", widgets.QMessageBox__Ok, widgets.QMessageBox__Ok)
                button.SetText(button.Text() + " again")
            })
        }()
    })

    window.SetCentralWidget(button)
    window.Show()

    widgets.QApplication_Exec()
}

Also maybe take a look here https://github.com/therecipe/examples/blob/master/advanced/widgets/goroutine/main.go

>All comments

Hey

You can simply run anything that would block the UI in a go routine and then use signals/slots or the helper function from https://github.com/therecipe/qt/issues/841#issuecomment-485217753 to update the UI.

Something like this should work

package main

import (
    "os"
    "time"

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

type mainThreadHelper struct {
    core.QObject

    _ func(f func()) `signal:"runOnMain,auto`
}

func (*mainThreadHelper) runOnMain(f func()) { f() }

var MainThreadRunner = NewMainThreadHelper(nil)

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

    window := widgets.NewQMainWindow(nil, 0)

    button := widgets.NewQPushButton2("click me", nil)
    button.ConnectClicked(func(bool) {
        go func() {
            time.Sleep(3 * time.Second) //do something that would block the UI in go routines

            MainThreadRunner.RunOnMain(func() {
                //again on the main thread, do the UI update
                //but don't do anything that would block the UI here
                widgets.QMessageBox_Information(nil, "OK", "Hello from main thread", widgets.QMessageBox__Ok, widgets.QMessageBox__Ok)
                button.SetText(button.Text() + " again")
            })
        }()
    })

    window.SetCentralWidget(button)
    window.Show()

    widgets.QApplication_Exec()
}

Also maybe take a look here https://github.com/therecipe/examples/blob/master/advanced/widgets/goroutine/main.go

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iMaxopoly picture iMaxopoly  路  3Comments

ismlsmile picture ismlsmile  路  5Comments

ohenepee picture ohenepee  路  4Comments

LimEJET picture LimEJET  路  6Comments

xlucas picture xlucas  路  7Comments