我一直在阅读有关Qt信号和插槽的信息,我正在尝试让它工作,但直到现在还没有成功。我希望有人能指出我正确的方向
我有两个文件homeCommand.cpp
和messagelogcommand.cpp
。我在QPlainTextEdit
中有一个messagelogcommand.cpp
对象,我想从homeCommand.cpp
更新
我怎么能用信号和插槽做到这一点?正在调用我的信号,因为我的QDebug每秒打印一次,但小部件不会更新。
这就是我想要做的事情:
在MessageLogCommand.h中
class MessageLogCommand : public QWidget
{
Q_OBJECT
public:
explicit MessageLogCommand(QWidget *parent = 0);
QLabel *homeLabel;
QPlainTextEdit *messageLog;
public Q_SLOTS:
void updateWidgets(const QString &text);
};
homeCommand.h
class homeCommand : public QWidget
{
Q_OBJECT
Q_SIGNALS:
void textChanged(const QString &text);
public:
explicit homeCommand(QWidget *parent = 0);
public slots:
void run(void);
void getHealthStatusPacket(void);
homeCommand.cpp
homeCommand::homeCommand(QWidget *parent) : QWidget(parent)
{
...
//Timer
QTimer *timer = new QTimer(this);
timer->setSingleShot(false);
connect(timer, SIGNAL(timeout()), this, SLOT(run()));
timer->start(1000);
setLayout(layout);
}
void homeCommand::run(void)
{
getHealthStatusPacket();
}
void homeCommand::getHealthStatusPacket(void)
{
...
Q_EMIT textChanged("ZOMG");
}
在MessageLogCommand.cpp
中 MessageLogCommand::MessageLogCommand(QWidget *parent) : QWidget(parent)
{
QGridLayout *layout = new QGridLayout;
QWidget::setFixedHeight(600);
//Sub-system Label
homeLabel = new QLabel("GSS Message Log");
QFont subsystemFont = homeLabel->font();
subsystemFont.setPointSize(12);
subsystemFont.setBold(true);
homeLabel->setFont(subsystemFont);
layout->addWidget(homeLabel, 0, 0);
//Event Log
messageLog = new QPlainTextEdit();
messageLog->setFixedHeight(500);
messageLog->setFixedWidth(600);
layout->addWidget(messageLog, 2,0);
setLayout(layout);
}
void MessageLogCommand::updateWidgets(const QString &text)
{
qDebug() << "Here";
messageLog->appendPlainText(text);
}
在main.cpp
中MessageLogCommand s;
homeCommand m;
QObject::connect(&m, SIGNAL(textChanged(QString)), &s, SLOT(updateWidgets(QString)));
答案 0 :(得分:1)
一个非常基本的例子是:
class MainClass:public QObject //class must be derived from QObject!
{
Q_OBJECT //this macro must be in the class definition
//so the moc compiler can generate the necessary glue code
public:
void doSomething() {
...
Q_EMIT textChanged(someText);
}
Q_SIGNALS:
void textChanged(const QString &text);
};
class SubClass:public QObject
{
Q_OBJECT
public Q_SLOTS:
void onTextChanged(const QString &text) { //do not inline
//do something
}
};
int main()
{
QApplication a;
MainClass m;
SubClass s;
QObject::connect(&m, SIGNAL(textChanged(QString)),
&s, SLOT(onTextChanged(QString))); //const and & are removed from
//the arguments
return a.exec(); //run the event loop
}
所以,有两件事很重要: 1.必须在从QObject派生的类中声明信号和槽 2.包含信号和槽声明的类必须将Q_OBJECT宏添加到类声明
为了简单起见:始终在头文件中声明包含信号或插槽的类(从不在.cpp文件中)。
答案 1 :(得分:0)
信号和广告位的一个非常好的起点是:http://woboq.com/blog/how-qt-signals-slots-work.html但官方Qt文档也是这样做的:http://qt-project.org/doc/qt-4.8/signalsandslots.html
基本上会发生什么:你声明了一些特殊的方法(信号和插槽),在编译阶段Qt生成额外的CPP文件,它们处理你的方法(moc)然后一切都被编译和链接在一起,最后当Qt或别人会发出一个信号,它会转到相应的位置。
答案 2 :(得分:-1)
我试着解释一下。
在main.h中你应该声明一个信号:
signals:
void textChanged(const QString& text);
在messagelog.h中你应该声明一个插槽:
public slots:
void updateWidgets(const QString& text);
在main.cpp中你应该发出这个信号:
void TheMethod() {
emit this->textChanged("Your text/value");
}
在messagelog.cpp中你应该得到这个值:
// Note: Normalized signal/slot signatures drop the consts and references.
connect(&a, SIGNAL(textChanged(QString)), this, SLOT(updateWidgets(QString)));
void updateWidgets(const QString& text) {
messageLog = new QPlainTextEdit();
messageLog->setFixedHeight(500);
messageLog->setFixedWidth(600);
messageLog->setPlainText(text)
layout->addWidget(messageLog, 2,0);
}
我认为它应该有效。
<强>更新强> 完整示例:https://dl.dropboxusercontent.com/u/29647980/test.zip