Russian Qt Forum

Qt => Qt Quick => Тема начата: Гурман от Май 14, 2019, 22:11



Название: [РЕШЕНО] Сигнал из QML в C++
Отправлено: Гурман от Май 14, 2019, 22:11
Есть на форме QListWidget, в котором ListView, сформированный из QStringList. Из него при нажатии надо получать в С++ коде текст нажатой строки. Привязку сигнала делал по образу примеров из Интернет, поскольку однозначного подробного описания как обычно нет. QML код примерно такой (лишнее убрано):

Код:
Item {
    id: topitem
    signal sendText(string text)

    ListView {
        model: StringList

        delegate: Rectangle {
            id: rectangle
            color: "yellow"

            MouseArea {
                z: -1
                anchors.fill: parent;
                onPressed: {
                    topitem.sendText( modelData )
                    rectangle.color = "lightyellow"
                }
                onReleased: {rectangle.color = "yellow"}
            }
            Text {
                id:itemName
                text: modelData
            }
        }
    }
}

Сигнал sendText(QString) подключен в С++ коде:

Код:
    QObject* o = (QObject*) ui->listWidget->rootObject();
    qWarning() << connect( o, SIGNAL(sendText(QString)), this, SLOT(see(QString)) );

Выдаёт true. В слоте see(QString) просто

Код:
void see(QString s){qWarning()<<s;}

Список отображается заполненный правильно строками из QStringList, при нажатии на пункты они мигают ярко жёлтым, но сигнал sendText() не приходит. ЧЯДНТ?


Название: Re: Сигнал из QML в C++
Отправлено: clingerwinger от Май 15, 2019, 13:27
Вы уверены что ваш "o" это тот самый итем, а не qml окно (или виджет)? Самым простым вариантом для проверки - сделать у topitem свойство:
Код:
objectName: "some name"
и потом проверить его у "o".
Но лучше было бы пробросить в качестве контекстного свойства какого-то слушателя в qml и дергать его слоты.


Название: Re: Сигнал из QML в C++
Отправлено: Гурман от Май 15, 2019, 13:34
Вы уверены что ваш "o" это тот самый итем, а не qml окно (или виджет)? Самым простым вариантом для проверки - сделать у topitem свойство:

Да, потому что если я убираю signal setText(string text) из QML кода Item, то соединение не выполняется, connect возвращает false. Если бы объект был другой, то соединение всё равно выполнилось бы.


Название: Re: Сигнал из QML в C++
Отправлено: Гурман от Май 15, 2019, 13:42
Сделал немного по-другому, так тоже описано в руководствах и в примерах - убрал все коннекты, убрал сигнал, а в MouseArea просто написал:                    
Код:
                onPressed: {
                    StringList.see("test")
                    rectangle.color = "lightyellow"
                }
теперь при клике получаю ошибку:
TypeError: Property 'see' of object <почему-то всё содержимое списка а не его имя> is not a function.
Ну как же... это же slot. Ладно, заменяю его на Q_INVOKABLE в public секции - та же фигня.


Название: Re: Сигнал из QML в C++
Отправлено: clingerwinger от Май 15, 2019, 14:21
Навскидку сложно сказать что у Вас не так, не все доступно. Набросал Вам минимальный пример.


Название: Re: Сигнал из QML в C++
Отправлено: Гурман от Май 15, 2019, 15:10
Всё, разобрался. Проблема была в другом. Я в начале когда рисовал интерфейс и положил на него QQuickWidget, в его проперти в дизайнере вбил имя QML файла. Там есть свойство source. И забыл. А UI приложения инициализируется до того, как у меня задаётся rootContext()->setContextProperty() - поскольку у меня этот контекст динамически меняется с изменениями QStringList. Получалось, что connect выполнялся, но не с тем корневым объектом, который связан с текущим списком строк. Увы, никаких сообщений при этом не было, что вводило в заблуждение. Сейчас у себя перенёс connect в место после переустановки корневого контекста - и всё заработало как надо.