Solved How to avoid QML error: “This is probably intended to be a signal handler but no signal of the target matches the name.”
-
I have working QML that has an
ApplicationWindow
with aLoader
. The loader has a default qml fileGameStart.qml
representing a screen with some startup activities. For simplicity, say the 1st screen can navigate to the 2nd screengamePlay.qml
and the 2nd can navigate back to the 1st. The navigation is done by the loaded item emitting a signal that theApplicationWindow
has slots for. All that happens in the slots is theLoader
's source gets modified.// RootWindow.qml import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Window 2.12 import QtQuick.Layouts 1.12 ApplicationWindow { id: mainWindow minimumWidth: Math.min(215 * Screen.pixelDensity, Screen.width) minimumHeight: Math.min(120 * Screen.pixelDensity, Screen.height) visible: true color: "turquoise" property string currentScreen: "GameStart.qml" Loader { id: dynamicLoader anchors.fill: parent source: currentScreen } Connections { target: dynamicLoader.item function onPlayGame() { currentScreen = "GamePlay.qml" console.log("currentScreen: ", currentScreen) } } Connections { target: dynamicLoader.item function onEndGame() { currentScreen = "GameStart.qml" console.log("currentScreen: ", currentScreen) } } }
The default screen and the other screen declare signals like this:
// GameStart.qml import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 Item { id: gameStart anchors.top: parent.top height: parent.height width: parent.width signal playGame RowLayout { id: layout anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter RoundButton { id: playButton text: "Play" width: 40 radius: 2 font.pointSize: 12 Layout.alignment: Qt.AlignVCenter onClicked: { // var players = selector.playerArray // for (var i =0; i < players.count; i++) { // console.log(players.itemAt(i).playerName) // game.addPlayer(players.itemAt(i).playerName) // } gameStart.playGame() } } } }
Things work the way I expect them to, but there is a runtime error message that pops up that I'd rather not have:
qrc:/qml/RootWindow.qml:25:5: QML Connections: Detected function "onPlayGame" in Connections element. This is probably intended to be a signal handler but no signal of the target matches the name.
My guess is this happens because I use as the
Connections
target: dynamicLoader.item and that is not a specific object id, but rather a dynamically loaded object. I am not able to use e.g.gameStart
orgamePlay
as targets of theConnections
inRootWindow.qml
, however. Those IDs are not recognized within that file.I suspect I have not discovered the idiomatic way of doing this and my way is kludgey. What should I do to avoid this runtime message?
EDIT: here's the GamePlay.qml file and also PlayerArea.qml
//GamePlay.qml import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 import QtQml.Models 2.12 import QtQml 2.12 Item { id: gamePlay signal endGame property var playerArray : game.getPlayers() ListModel { id: playerLayoutModel ListElement { property var row: 1 property var column: 0 } ListElement { property var row: 1 property var column: 2 } ListElement { property var row: 0 property var column: 1 } ListElement { property var row: 2 property var column: 1 } } ColumnLayout { id: mainColumn spacing: 2 anchors.fill: parent anchors.horizontalCenter: parent.horizontalCenter Rectangle { Layout.alignment: Qt.AlignHCenter height: 100 width: 250 color: "turquoise" RowLayout { id: gameButtonsLayout anchors.fill: parent Button { id: deal Layout.preferredHeight: 50 Layout.preferredWidth: 80 text: "Deal" } Button { id: end Layout.preferredHeight: 50 Layout.preferredWidth: 80 text: "End Game" onClicked: { gamePlay.endGame() } } Button { id: save Layout.preferredHeight: 50 Layout.preferredWidth: 80 text: "Save Game" } } } Rectangle { Layout.fillHeight: true Layout.fillWidth: true anchors.horizontalCenter: Layout.horizontalCenter color: "turquoise" GridLayout { id: gridnew columns: 3 rows: 3 anchors.fill: parent property var playerCnt: playerArray.length Repeater { model: playerLayoutModel delegate: playerArea } Component { id: playerArea PlayerArea { color: "red" playerName: playerArray[index] Layout.row: model.row Layout.column: model.column Layout.fillHeight: true Layout.fillWidth: true enabled: gridnew.playerCnt > index ? true : false opacity: gridnew.playerCnt > index ? true : false } } } Component.onCompleted: { console.log("rectangle containing grid size: ", height, width) console.log("rectangle center: ", horizontalCenter, verticalCenter) } } } }
// GamePlay.qml import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 Item { id: playerArea property string playerName property string cardText property string color Component.onCompleted: { var globalCoords = playerArea.mapToItem(gamePlay, x, y) console.log("playerArea.enabled: ", enabled) console.log("playerArea coords: ", x, y) console.log("area at coords: ", globalCoords.x, globalCoords.y) } ColumnLayout { // Card { // } // Rectangle { // TODO remove when graphical card ready // height: 20 // width: 20 anchors.horizontalCenter: parent.horizontalCenter Label { color: playerArea.color height: 50 width: 50 text: cardText } // } Label { id: nameLabel height: 50 width: 50 text: playerName } Button { id: playButton height: 50 width: 50 text: "Play Card" } } }
-
@rhvonlehe https://doc.qt.io/qt-6/qml-qtqml-connections.html#ignoreUnknownSignals-prop
While the Loader is loading, Loader.item doesn't point to a valid object. As such, the signal expected by the Connections instance also won't exist.
-
I wouldn't have thought there would be a property to ignore a runtime error message. It definitely works, though. Thank you.
There's a similar Stack Overflow message that you can answer and take credit for there if you like. I can't answer it myself for a day or two.
-
@rhvonlehe said in How to avoid QML error: “This is probably intended to be a signal handler but no signal of the target matches the name.”:
I wouldn't have thought there would be a property to ignore a runtime error message.
That's what
Connections.ignoreUnknownSignals
is. "If this property is set to true, such errors are ignored."
Logging the condition, depending on the Qt Declarative version, is implemented as:} else if (!d->ignoreUnknownSignals && propName.startsWith(QLatin1String("on")) && propName.length() > 2 && propName.at(2).isUpper()) { qmlWarning(this) << tr("Detected function \"%1\" in Connections element. " "This is probably intended to be a signal handler but no " "signal of the target matches the name.").arg(propName); }
Or do you mean ignore warning messages in general? QLoggingCategory configuration can do that, as can qInstallMessageHandler.
There's a similar Stack Overflow message that you can answer and take credit for there if you like. I can't answer it myself for a day or two.
I never got into Stack Overflow point collecting. Thanks for the offer.
-
@jeremy_k
"I never got into Stack Overflow point collecting. Thanks for the offer."I like you even more now.
Marked as solved. I forgot to do this yesterday.