我有一个数据读取器,它从缓冲区获取数据并将输出显示到控制台。现在我想实时将数据看到textedit。 我已经看到一些示例显示如何从文本文件中读取数据(非实时)。
请找到附件。
/* Create a DataReader for the chatMessageTopic Topic (using the appropriate QoS). */
parentReader = chatSubscriber->create_datareader(
chatMessageTopic.in(),
DATAREADER_QOS_USE_TOPIC_QOS,
NULL,
STATUS_MASK_NONE);
checkHandle(parentReader.in(), "DDS::Subscriber::create_datareader");
/* Narrow the abstract parent into its typed representative. */
chatAdmin = Chat::ChatMessageDataReader::_narrow(parentReader.in());
checkHandle(chatAdmin.in(), "Chat::ChatMessageDataReader::_narrow");
/* Print a message that the MessageBoard has opened. */
cout << "MessageBoard has opened: send ChatMessages...." << endl << endl;
while (!terminated) {
/* Note: using read does not remove the samples from
unregistered instances from the DataReader. This means
that the DataRase would use more and more resources.
That's why we use take here instead. */
status = chatAdmin->take(
msgSeq,
infoSeq,
LENGTH_UNLIMITED,
ANY_SAMPLE_STATE,
ANY_VIEW_STATE,
ALIVE_INSTANCE_STATE );
checkStatus(status, "Chat::ChatMessageDataReader::take");
for (DDS::ULong i = 0; i < msgSeq->length(); i++) {
ChatMessage *msg = &(msgSeq[i]);
cout << msg->index << ": " << msg->content << endl;
fflush(stdout);
}
status = chatAdmin->return_loan(msgSeq, infoSeq);
checkStatus(status, "Chat::ChatMessageDataReader::return_loan");
答案 0 :(得分:1)
您可能不希望您的UI在1000Hz时刷新。因此,在繁忙的循环中运行此代码毫无意义。相反,以合理的刷新率运行它,例如, 30Hz,来自计时器。
出于性能原因,它可能有助于发出行批次以及日志的各个行:
让我们抽象出来:
class DDSProcessor : public QObject {
Q_OBJECT
QBasicTimer m_timer;
DDS::Subscriber * m_chatSubscriber;
Chat::ChatMessageDataReader * m_chatDataReader = nullptr;
...
Q_SIGNAL void message(const QString &);
Q_SIGNAL void messages(const QStringList &);
void timerEvent(QTimerEvent * ev) {
if (ev->timerId() != m_timer.timerId()) return;
auto status = chatAdmin->take(
msgSeq,
infoSeq,
LENGTH_UNLIMITED,
ANY_SAMPLE_STATE,
ANY_VIEW_STATE,
ALIVE_INSTANCE_STATE );
checkStatus(status, "Chat::ChatMessageDataReader::take");
QStringList texts;
for (DDS::ULong i = 0; i < msgSeq->length(); i++) {
auto msg = &(msgSeq[i]);
auto text = tr("%1: %2").arg(msg->index).arg(msg->content);
texts << text;
emit message(text);
}
emit messages(texts);
status = chatAdmin->return_loan(msgSeq, infoSeq);
checkStatus(status, "Chat::ChatMessageDataReader::return_loan");
}
public:
void start() {
auto reader = m_chatSubscriber->create_datareader(
m_chatMessageTopic.in(), ...);
checkHandle(read.in(), "DDS::Subscriber::create_datareader");
m_chatDataReader = Chat::ChatMessageDataReader::_narrow(reader.in());
checkHandler(m_chatDataReader.in(), "Chat::ChatMessageDataReader::_narrow");
auto text = tr("MessageBoard had opened: send ChatMessages.");
emit message(text);
emit messages(text);
m_timer.start(this, 1000/30);
}
...
};
我对DDS库不够熟悉,但是您应该使用一些回调来通知,然后您将从回调中发出信号。这将消除对显式UI更新循环的需求。
然后,您在UI中所要做的就是对DDSProcessor发出的消息采取行动:
void setup(DDSProcessor * src, QTextEdit * dst) {
connect(src, &DDSProcessor::message, dst, &QTextEdit::append);
}
请注意,QTextEdit
和QPlainTextEdit
都非常慢,不适合快速记录。最简单的解决方法是使用带有QListView
的列表模型,并利用批量日志条目信号:
int main(int argc, char ** argv) {
QApplication app(argc, argv);
QStringListModel logModel;
QListView view;
DDSProcessor processor;
QObject::connect(&processor, &DDSProcessor::messages, &logModel, [&](const QStringList & texts){
auto row = logModel.rowCount();
logModel.insertRows(row, texts.count());
for (auto const & text : texts)
logModel.setData(model.index(row++), text);
});
view.setModel(&logModel);
view.show();
view.setUniformItemSizes(true); // needed for performance
...
return app.exec();
}
答案 1 :(得分:0)
这是同步登录GUI的最小示例:
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QPlainTextEdit edit;
edit.show();
int x = 0;
while (edit.isVisible()) {
x++;
edit.appendPlainText(QString("test %1").arg(x));
qApp->processEvents();
}
return 0;
}