首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >查看新项目的QStringList

查看新项目的QStringList
EN

Stack Overflow用户
提问于 2016-10-14 19:02:00
回答 3查看 225关注 0票数 0

我正在QT框架中开发一个数据记录器。我打算将日志字符串保存到文件中,并在一个单独的监视线程中打印到控制台。在这个单独的线程中,我需要查看添加的新项目的QStringList。如果有新的项目,我喜欢他们和日志。我想知道Qt框架中用于此的机制是什么。在STD中,我使用condition_variable来执行以下任务:

代码语言:javascript
运行
复制
/*!
 * \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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-14 21:17:59

这是一个做这个信号和插槽的例子。您可能想做自己的基准测试,以测试这是否符合您的需要。还请注意,虽然信号和插槽保证线程安全,但它们不能保证消息以相同的顺序出现。尽管如此,我已经使用这个机制多年了,但它还没有发生在我身上。

首先,创建两个类:

洛吉

代码语言:javascript
运行
复制
// 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文件:

代码语言:javascript
运行
复制
#include "loggee.hpp"

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

记录器

代码语言:javascript
运行
复制
#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文件:

代码语言:javascript
运行
复制
#include <QDebug>
#include <QThread>

#include "logger.hpp"

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

剩下的

代码语言:javascript
运行
复制
#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的时隙连接起来。这是默认的,但我明确地说明了这一点,以表明您可以更改它(即,如果两个线程都驻留在同一个线程中,就可以将该插槽的执行排在队列中)。

然后,我使Loggee发出一个信号。它得到正确的调度,并导致日志槽在接收器的线程中执行。

emit#define emit /*null*/,所以如果愿意,可以省略它。

票数 1
EN

Stack Overflow用户

发布于 2016-10-14 21:01:39

在Qt中有几种执行通知的方法。

信号和插槽

可以在线程之间发送信号和插槽,在建立连接时,将连接类型设置为Qt::QueuedConnection或Qt::BlockingQueuedConnection

您可能希望在QStringList周围创建一个包装类,以便修改可以触发其他类侦听的信号。

QMutex和QWaitCondition

您可以像以前一样使用Qt线程同步类QMutexQWaitCondition进行经典的手动同步。当使用QMutex时,QMutexLocker对于范围锁定和QMutex的发布非常有用。

票数 2
EN

Stack Overflow用户

发布于 2016-10-15 09:45:23

如果您只是在寻找您一直在使用的类的Qt等价物:

代码语言:javascript
运行
复制
std::mutex -> QMutex
std::condition_variable -> QWaitCondition
std::unique_lock -> QMutexLocker
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40050318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档