therecipe / qt

Qt binding for Go (Golang) with support for Windows / macOS / Linux / FreeBSD / Android / iOS / Sailfish OS / Raspberry Pi / AsteroidOS / Ubuntu Touch / JavaScript / WebAssembly
GNU Lesser General Public License v3.0
10.5k stars 748 forks source link

ConnectSendToGo slot isn't executed #1208

Open LRocc opened 3 years ago

LRocc commented 3 years ago

New to qml and Qt, i am trying to get the hang with signals and slots. I am not entirely sure why this happens. I have a login form with two TextFields, a login button that when pressed should sent back to go the content of those 2 text fields. When the button is pressed, i get SIGSEGV error instead. Specifically:

fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x265a014]

runtime stack:
runtime.throw(0x3e4b41a, 0x2a)
        runtime/panic.go:774 +0x72
runtime.sigpanic()
        runtime/signal_unix.go:378 +0x47c

goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x2373460, 0xc0004c5f28, 0x8678b80)
        runtime/cgocall.go:128 +0x5b fp=0xc0004c5ef8 sp=0xc0004c5ec0 pc=0x957ccb
github.com/therecipe/qt/widgets._Cfunc_QApplication_QApplication_Exec(0x0)
        _cgo_gotypes.go:9044 +0x49 fp=0xc0004c5f28 sp=0xc0004c5ef8 pc=0x151e049
github.com/therecipe/qt/widgets.QApplication_Exec(...)
        github.com/therecipe/qt/widgets/widgets.go:9694
main.main()
        github.com/therecipe/box/full/full_box.go:25 +0x69 fp=0xc0004c5f60 sp=0xc0004c5f28 pc=0x20bd449
runtime.main()
        runtime/proc.go:203 +0x21e fp=0xc0004c5fe0 sp=0xc0004c5f60 pc=0x98429e
runtime.goexit()
        runtime/asm_amd64.s:1357 +0x1 fp=0xc0004c5fe8 sp=0xc0004c5fe0 pc=0x9af151

goroutine 19 [IO wait]:
internal/poll.runtime_pollWait(0x7f0dc45feea8, 0x72, 0x0)
        runtime/netpoll.go:184 +0x55
internal/poll.(*pollDesc).wait(0xc0001b8018, 0x72, 0x0, 0x0, 0x3df44e1)
        internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
        internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Accept(0xc0001b8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        internal/poll/fd_unix.go:384 +0x1f8
net.(*netFD).accept(0xc0001b8000, 0xc000067d88, 0xf72904, 0xc0001b40a0)
        net/fd_unix.go:238 +0x42
net.(*TCPListener).accept(0xc00000e040, 0x5ff9d2a2, 0xc000067d88, 0x9d28b6)
        net/tcpsock_posix.go:139 +0x32
net.(*TCPListener).Accept(0xc00000e040, 0xc000067dd8, 0x18, 0xc00009a480, 0xf71e1e)
        net/tcpsock.go:261 +0x47
net/http.(*Server).Serve(0xc0001b4000, 0x43d76e0, 0xc00000e040, 0x0, 0x0)
        net/http/server.go:2896 +0x286
net/http.(*Server).ListenAndServe(0xc0001b4000, 0xc0001b4000, 0x0)
        net/http/server.go:2825 +0xb7
net/http.ListenAndServe(0x3df87f2, 0xe, 0x0, 0x0, 0x0, 0xc0000a6bb0)
        net/http/server.go:3080 +0x74
created by github.com/therecipe/qt/interop.init.0
        github.com/therecipe/qt/interop/interop_http_api.go:55 +0x135

goroutine 20 [IO wait]:
internal/poll.runtime_pollWait(0x7f0dc45fedd8, 0x72, 0xffffffffffffffff)
        runtime/netpoll.go:184 +0x55
internal/poll.(*pollDesc).wait(0xc0002a6018, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
        internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
        internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc0002a6000, 0xc0002aa000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        internal/poll/fd_unix.go:169 +0x1cf
net.(*netFD).Read(0xc0002a6000, 0xc0002aa000, 0x1000, 0x1000, 0xc0002919e8, 0x9dad3d, 0xc0002a6000)
        net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc0000b2070, 0xc0002aa000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        net/net.go:184 +0x68
net/http.(*connReader).Read(0xc0000a9080, 0xc0002aa000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        net/http/server.go:785 +0xf4
bufio.(*Reader).fill(0xc0000b4240)
        bufio/bufio.go:100 +0x103
bufio.(*Reader).Peek(0xc0000b4240, 0x4, 0x0, 0x0, 0x0, 0x0, 0xc000291ad0)
        bufio/bufio.go:138 +0x4f
net/http.(*conn).readRequest(0xc000148aa0, 0x43eb060, 0xc0000942c0, 0x0, 0x0, 0x0)
        net/http/server.go:962 +0xb3b
net/http.(*conn).serve(0xc000148aa0, 0x43eb060, 0xc0000942c0)
        net/http/server.go:1817 +0x6d4
created by net/http.(*Server).Serve
        net/http/server.go:2927 +0x38e

Process finished with exit code 0 

Here's my UI code:

package UI

import (
    "fmt"
    _ "github.com/heyuan110/gorepertory/logger"
    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/gui"
    "github.com/therecipe/qt/qml"
    "github.com/therecipe/qt/quickcontrols2"
    "os"
)
type QmlBridge struct {
    core.QObject
    //_ func(username string,password string) bool `signal:sendToQml`
    _ func(username string,password string )bool `slot:sendToGo`
}

func MakeUI() {
    var qmlBridge *QmlBridge
    qmlBridge = NewQmlBridge(nil)
    // Create application
    app := gui.NewQGuiApplication(len(os.Args), os.Args)

    // Enable high DPI scaling
    app.SetAttribute(core.Qt__AA_EnableHighDpiScaling, true)

    // Use the material style for qml
    quickcontrols2.QQuickStyle_SetStyle("material")

    // Create a QML application engine
    engine := qml.NewQQmlApplicationEngine(nil)
    engine.RootContext().SetContextProperty("qmlBridge", qmlBridge)
    //QmlBridgeVar.ConnectSendToQml(func(username string,password string){
    //
    //})
    qmlBridge.ConnectSendToGo(func(username string, password string){
        fmt.Println(username,password)
    })
    // Load the main qml file
    engine.Load(core.NewQUrl3("UI/main.qml", 0))
    // Execute app
    gui.QGuiApplication_Exec()

}

And my qml:

import QtQuick 2.0
import QtQuick.Controls 2.1
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    title: "Bouncer"
    property int margin: 11
    minimumWidth: 600
    minimumHeight: 450

    ColumnLayout {
        id: mainLayout
        anchors.fill: parent
        anchors.margins: margin
        GroupBox {
            id: rowBox
            title: "Login"
            Layout.fillWidth: true

            RowLayout {
                id: rowLayout
                anchors.fill: parent
                TextField {
                    id: usernameField
                    placeholderText: "Username"
                    Layout.fillWidth: true
                }
                TextField {
                    id: passwrdField
                    placeholderText: "Password"
                    Layout.fillWidth: true
                }
                Button {
                    id: loginButton
                    text: "Login"
                    MouseArea{
                        id: loginMouseArea
                        anchors.fill: parent
                        onClicked: qmlBridge.sendToGo(usernameField.text, passwrdField.text)
                    }

                }

            }
        }

    }

}