观看QStringList中的新项目 [英] Watch a QStringList for new items

查看:112
本文介绍了观看QStringList中的新项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用QT框架中的数据记录器.我打算将日志字符串保存到文件中,并在单独的观察程序线程中打印到控制台.在那个单独的线程中,我需要查看我的QStringList中是否添加了新项目.如果有新物品,我将它们摆出并记录.我想知道Qt框架中用于此的机制是什么.在STD lib中,我使用condition_variable来完成此任务,如下所示:

I am working on a data logger in QT framework. I Intend to save log strings to files and print to the console in a separate watcher thread. In that separate thread I need to watch my QStringList for new items added. If there are new items I deque them and log. I was wondering what is the mechanism used for this in Qt framework. In STD lib i used condition_variable for this task like this:

/*!
 * \brief puts a \ref logline_t object at the end of the queue
 * @param s object to be added to queue
 */
void CLogger::push_back(logline_t* s)
{
    unique_lock<mutex> ul(m_mutex2);
    s->queSize = m_data.size();
    m_data.emplace_back(move(s));
    m_cv.notify_all();
}

/*!
 * \brief takes a \ref logline_t object from the beggining of the queue
 * @return first \ref logline_t object
 */
CLogger::logline_t CLogger::pop_front()
{
    unique_lock<mutex> ul(m_mutex2);
    m_cv.wait(ul, [this]() { return !m_data.empty(); });

    assert(m_data.front());
    logline_t retVal = move(*m_data.front());

    delete m_data.front();
    m_data.front() = NULL;

    m_data.pop_front();

    return retVal;
}

m_cv是条件变量对象. QT如何获得此功能?我敢打赌,还有更好的方法:).我将不胜感激. Ps:我知道指针函数的参数未声明,这是一个旧代码...:P

m_cv is the conditional variable object. How can this functionality be acquired with QT? I bet there is a lot better way :). I would appreciate all help. Ps: I know pointer functions parameters are not asserted, this is an old code... :P

推荐答案

以下是执行此信号和插槽的示例.您可能需要做自己的基准测试,以测试这是否符合您的需求.另请注意,尽管信号和插槽可保证线程安全,但它们并不能保证消息的显示顺序与发送顺序相同.话虽这么说,我已经使用这种机制多年了,但对我来说却尚未发生.

Here's an example of doing this signals and slots. You may want to do your own benchmarks to test whether this fits your needs. Please also note that while signals and slots guarantee thread-safety, they don't guarantee that the messages will appear in the same order they were sent. That being said, I've used this mechanism for years and it has yet to happen for me.

首先,创建几个类:

// loggee.hpp
#ifndef LOGGEE_HPP
#define LOGGEE_HPP

#include <QObject>

class Loggee : public QObject
{
    Q_OBJECT
public:
    using QObject::QObject;


    void someEventHappened(int id);

signals:

    void newLogLineNotify(QString const&);
};

#endif // LOGGEE_HPP

和.cpp文件:

#include "loggee.hpp"

void Loggee::someEventHappened(int id)
{
    auto toLog = QString::number(id);
    emit newLogLineNotify(toLog);
}

记录器

#ifndef LOGGER_HPP
#define LOGGER_HPP

#include <QObject>

class Logger : public QObject
{
    Q_OBJECT
public:
    using QObject::QObject;

signals:

public slots:

    void onLogEventHappened(QString const&);

};

#endif // LOGGER_HPP

和.cpp文件:

#include <QDebug>
#include <QThread>

#include "logger.hpp"

void Logger::onLogEventHappened(QString const& str)
{
    qDebug() << QThread::currentThreadId() << str;
}

其余

#include <QDebug>
#include <QThread>
#include <QCoreApplication>
#include <QTimer>
#include "logger.hpp"
#include "loggee.hpp"

int main(int argc, char** argv)
{
    QCoreApplication a(argc, argv);
    QThread t;
    t.start();

    Logger foo;
    Loggee bar;
    foo.moveToThread(&t);

    QObject::connect(&bar, &Loggee::newLogLineNotify,
                     &foo, &Logger::onLogEventHappened,
                     Qt::AutoConnection);

    qDebug() << "Current thread id: " << QThread::currentThreadId();

    bar.someEventHappened(42);

    QTimer::singleShot(3000, [&]{ bar.someEventHappened(43); });

    return a.exec();
}

在此演示中,我创建一个QThread和一个Logger,并将对该新Logger插槽的处理移到该新线程的事件循环中.然后,使用Qt::AutoConnectionLoggee的信号与Logger的插槽连接.这是默认设置,但我明确表示要表明您可以更改此设置(即更改为Qt::QueuedConnection,即使两个线程都位于同一线程中,也会将插槽的执行排队).

In this demo, I create a QThread and a Logger, move handling of this new Logger's slots to this new thread's event loop. Then I connect Loggee's signal with Logger's slot using Qt::AutoConnection. This is the default but I stated it explicitly to show that you can change this (i.e. to Qt::QueuedConnection which would queue the execution of the slot even if both threads lived in the same thread).

然后我使Loggee发出¹单数.它得到了正确的调度,并导致在接收者的线程中执行日志记录插槽.

Then I cause the Loggee to emit¹ a singal. It gets properly scheduled and causes the logging slot to be executed in the receiver's thread.

¹emit#define emit /*null*/,因此您可以根据需要将其忽略

¹ emit is #define emit /*null*/, so you can omit it if you want

这篇关于观看QStringList中的新项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆