[英]Emitting signal not updating the values in GUI
我正在尝试制作一个非常基本的时间表应用程序,以学习Qt的基础知识。 我对此进行了相当多的研究,似乎无法得到我的问题的答案,当我改变主题的值但发射信号没有更新GUI时,我发出信号。 它肯定会改变代码中的值,但QML GUI在运行时不会更新它。
我有一个名为Day的课程,其中包含以下Q_PROPERTY:
Q_PROPERTY(Period *getPeriod READ getPeriod WRITE setPeriod NOTIFY periodChanged)
Q_PROPERTY(QString getDay READ getDay WRITE setDay NOTIFY dayChanged)
和一个持有期间的成员
Period *m_period = new Period[10]; //Of type Period (my other class) which holds my subject string
我还有日期和时段的getter和setter(如Q_PROPERTY中所示),这两个用于设置/获取主题:
Q_INVOKABLE QString getSubject(int t){
return m_period[t].getSub();
};
Q_INVOKABLE void setSubject(int t, QString subj){
m_period[t].setSub(subj);
emit periodChanged();
};
有以下信号:
void periodChanged();
void dayChanged();
我还有一个名为Period的类,其中包含以下Q_PROPERTY:
Q_PROPERTY(QString getSub READ getSub WRITE setSub NOTIFY subChanged)
以及持有主题名称的成员:
QString subject;
我的Period类保存了在day中调用的函数来实际更改QString主题:
QString getSub(){
return subject;
};
void setSub(QString sub){
subject = sub;
emit subChanged();
};
有以下信号:
void subChanged();
所以当我在QML中使用setSubject()更改主题时,它是否应该发出periodChanged()和subChanged()信号,这应该更新GUI? 我认为它会,但它似乎没有工作。
作为参考,这基本上是我在QML中实现它的方式:
Label { text: monday.getSubject(2) } //How I display the Subject, the parameter being the period number
Button{
text: "Enter"
onClicked:{
monday.setSubject(2, "RANDOM_TEXT") //How I set the subject at run time, with the first argument being the period number and second the text I want to change it to
}
以下是main和class文件:
main.cpp中
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
qmlRegisterType<Day>("Timetable", 1,0, "Day");
qmlRegisterType<Period>("Timetable", 1,0, "Period");
QQmlApplicationEngine engine;
Day monday;
engine.rootContext()->setContextProperty("monday", &monday);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QQmlComponent component(&engine, QUrl::fromLocalFile("main.qml"));
component.create();
return app.exec();
}
Day.h
class Day : public QObject
{
Q_OBJECT
Q_PROPERTY(Period *getPeriod READ getPeriod WRITE setPeriod NOTIFY periodChanged)
private:
Period *m_period = new Period[10];
public:
Day(QObject *parent = 0);
~Day();
Period* getPeriod();
Q_INVOKABLE void setPeriod(Period *p);
Q_INVOKABLE QString getSubject(int t){
return m_period[t].getSub();
};
Q_INVOKABLE void setSubject(int t, QString subj){
m_period[t].setSub(subj);
emit periodChanged();
};
signals:
void periodChanged();
};
Period.h
class Period: public QObject
{
Q_OBJECT
Q_PROPERTY(QString getSub READ getSub WRITE setSub NOTIFY subChanged)
private:
QString subject;
public:
Period(QObject *parent = 0);
~Period();
QString getSub(){
return subject;
};
void setSub(QString sub){
subject = sub;
emit subChanged();
};
signals:
void subChanged();
};
main.qml
ApplicationWindow {
id: mainWindow
visible: true
title: "Timetable App"
property int margin: 11
width: mainLayout.implicitWidth + 2 * margin
height: mainLayout.implicitHeight + 2 * margin
minimumWidth: 800
minimumHeight: 600
ColumnLayout {
id: mainLayout
anchors.fill: parent
anchors.margins: margin
GroupBox{
id: timetable
title: "Timetable"
Layout.fillWidth: true
Layout.fillHeight: true
GridLayout {
id: gridLayout
rows: 11
flow: GridLayout.TopToBottom
anchors.fill: parent
Layout.fillWidth: true
Layout.fillHeight: true
Label { }
Label { text: "8:00" }
Label { text: ...} // Added Labels for times from 8:00 to 17:00
Label { text: "Monday" }
Label { text: monday.getSubject(0) }
Label { text: monday.getSubject(1) }
Label { text: ...} // Added Labels to display subjects for monday at different times, also did the same for the rest of the week
}
}
RowLayout{
Button{
text: "Enter"
onClicked:{
monday.setSubject(1, "RANDOM_TEXT") // Set the second period of monday to "RANDOM_TEXT"
console.log(monday.getSubject(1)) // To check if actually set
}
}
}
}
}
您的问题是您通过QML中的方法调用而不是通过属性绑定来检索值。
像这样的QML代码应该更新
text: monday.getPeriod.getSub
显然,调用属性“getSomething”有点奇怪。
现在,您的m_period
建议单个Day
对象将具有多个Period
,这表明您可能需要list属性而不是单个Period
对象。 就像是
Q_PROPERTY(QList<Period*> periods READ getPeriods NOTIFY periodsChanged);
使用QML中的那个有点像这样
text: monday.periods[0].getSub
或者甚至使用例如Repeater
Label { text: "Monday" }
Repeater {
model: monday.periods
Label {
text: modelData.getSub
}
}
与您的更新问题无关但也很重要: NOTIFY
信号触发绑定更新,因此您不希望不必要地发出它们。 即发出这些值的setter应首先检查新值是否实际上与旧值不同,并且仅在它们发出时才发出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.