- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有两个对象,它们位于不同的线程中,我试图确定所使用的模式是否是线程安全的。
第一个对象是 QObject 派生的,存在于(创建于)主 Qt 线程中。该类包含一些应从 QML 调用的 Q_INVOKABLE
方法、一些定义为 signals:
的 signal*()
方法和一些 Emit *()
(普通)方法,我用作包装器来发出信号。例如:
void MyQObjectClass::EmitStatus(void) {
emit signalStatusChange(_status);
}
我通常在 QML 中监听这些信号。
第二个对象不是 QObject 派生的,存在于第二个线程 (pthread
) 中。该线程运行自己的事件循环 (libev) 并分派(dispatch)事件。我不能在此线程中使用与 Qt 相关的任何内容,因为我需要自定义 libev
事件循环。在这个对象上,我定义了一些 Notify*()
方法,这些方法将通过 libev
发送异步事件以供回调接收。
我需要能够在两个对象/线程之间进行通信,但我不确定如何安全地进行通信。
实际的设计是让pthread
线程对象直接调用不同的Emit*()
方法,这样QObject就可以正确的将信息传递给Qt/QML。如果我需要将信息从 Qt/QML 发送到 pthread
/libev
对象,我将调用(从 Qt 线程)Notify*()
方法。
阅读时Accessing QObject Subclasses from Other Threads ,它说:
QObject and all of its subclasses are not thread-safe. This includes the entire event delivery system.
但进一步指出:
On the other hand, you can safely emit signals from your QThread::run() implementation, because signal emission is thread-safe.
所以我的问题是,上面描述的设计是线程安全的吗?我能否安全地调用 myQObject->EmitMySignal()
,而后者又会调用 emit signalMySignal()
,所有这些都来自 pthread
对象?
最佳答案
我将演示如何使用事件而不是您不能使用的信号和插槽来实现您想要的(因为一侧不是 QObject
派生的)
class MyObjectClass : public QObject
{
Q_OBJECT
public:
virtual bool event(QEvent *event) override
{
bool result = true;
if(event->type() == QEvent::User+1)
emit signalStatusChange(_status);
else
result = QObject::event(event); //call direct parent's event here!
return result;
}
};
在您的另一个线程中,您将执行此操作:
MyObjectClass *p; //holds pointer to the instance in main thread
qApp->postEvent(p, new QEvent(QEvent::User+1));
这将检索指向位于主线程中的应用程序的指针,并将事件发布到其事件循环中。然而,事件将从调用中异步处理,因此行为将与您现在所做的不同。但它会更安全,恕我直言,更优雅。您可以根据需要添加任意数量的类型。如果您还没有处理事件,请不要忘记将事件传播给父级!
关于c++ - 从另一个(非 qt)线程调用 QObject 方法的线程安全性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40916479/
以下是我遇到的编译错误: /usr/lib/qt-3.3/include/qobject.h: In copy constructor Product::Product(const Product&)
class CHIProjectData : public QObject { public: CHIProjectData(); CHIProjectData(QMap aProje
这个问题在这里已经有了答案: Could I have copy constructor for subclass of QObject? (3 个答案) 关闭 7 年前。 我收到错误: C:\Qt
将一个项目从 Qt4 迁移到 Qt5 我得到了这个错误,我已经研究过,显然你不能从 QObject 创建一个派生类的复制构造函数(这太不可思议了,因为这段代码不是我的,它应该在以前的版本中编译).复制
我试图返回一个派生自 QObject 的类,但出现以下错误 Error : 'QObject::QObject' : cannot access private member declared in
我正在编写一些派生自 QObject 的 Qt 类,它看起来像: class A : public QObject { Q_OBJECT public: A() : QObject() {}
考虑以下代码: #include class A : public QObject { Q_OBJECT public: A(QObject* parent = 0)
我似乎需要 QObject 类型的 p 实例,我已经扩展了 QObject 并在 fileprocessor.h 中定义了关键字 Q_OBJECT,我不确定我还能做什么。 -文件处理器.h #ifnd
我有一个继承 QObject 的类 BatchItem,还有几个继承自 BatchItem 的类: #ifndef BATCHITEM_H #define BATCHITEM_H #include
这是代码: void invokeQMLFunction2Arg(QObject * object, QString func, QVariant p1, QVariant p2) { QMe
我读过 documentation对于 QObject::connect(对于 Qt 5.4),但我对重载有疑问 QMetaObject::Connection QObject::connect(co
我最近一直在使用QTCreator,我爱上了ATM。不幸的是,我想将它与 Python 一起使用,但我遇到了问题。我遇到的最大问题是发现我的应用程序上下文的子级返回 None。 main.py imp
使用 #include 有什么区别吗?和 #include ? 这两个似乎都有效,所以必须有一些原因来说明为什么 #include是首选吗? 最佳答案 任何不带 .h 扩展名的标准 Qt 头文件都保证
我写的Python代码看起来像这样: class Regularblock(QGraphicsItem): def __init__(self): super(QGraphic
Qt 框架有一个 signal for all QObjects which is emmited before destruction那个QObject。此事件可用于在它指向的对象被销毁时自动清空一
我想创建 SerialPort 类,它可以自动接收消息,然后发出信号。 但是当我编译它时显示错误信息: error: 'QObject' is an ambiguous base of 'Serial
(C++/Qt) 我有一个指向 QObject 的智能指针。让我们说一个 QWeakPointer。由于某些外部原因(可能发生在另一个对象中或由于某个事件),指向的对象可能会被销毁。因为我有一个智能指
QObject 析构函数的 Qt 引用说: 进出该对象的所有信号都会自动断开,该对象的任何未决发布事件都会从事件队列中删除。但是,使用 deleteLater() 通常比删除更安全直接一个 QObje
您好,我需要从后台进行一些套接字通信,我为此使用了QtConcurrent::run,但给了我警告。 QObject: Cannot create children for a parent that
如何打破 QObject 的父子所有权?似乎不再有明确的方法来做到这一点。打电话就够了 QObject::setParent(NULL) 最佳答案 你是对的。制作 QObject一个孤儿,简单地做 /
我是一名优秀的程序员,十分优秀!