- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在修改一个多线程 Qt 应用程序并且遇到了一个不可预见的行为。
我有一个从 QThread 继承的类 WorkerThread,其中的方法 run()
正在做一些工作。 WorkerThread 对象的插槽 handleSuccess()
连接到来自另一个主线程的信号,该信号是响应来自服务器的异步传入连接而发出的。据我了解,当 run()
正在运行时,流控制不在事件循环的 exec()
中,因此无法调用插槽。相反,我在应用程序的日志中看到线程正在 run()
的中间点执行它的工作,然后立即进入槽而不做任何准备。
class WorkerThread : public QThread {
Q_OBJECT
public:
WorkerThread() { moveToThread(this); /* further initialization */ }
void run();
void foo();
public slots:
void handleSuccess(const QByteArray &);
void shutdown();
private:
QMutex mutex;
MyResource resource;
volatile bool mShutdown;
/* ... other declarations */
};
void WorkerThread::foo() {
QMutexLocker locker(&mutex);
/* Working with the guarded resource */
}
void WorkerThread::run() {
QEventLoop signalWaiterEventLoop;
connect(this, SIGNAL(terminated()), &signalWaiterEventLoop, SLOT(quit()), Qt::QueuedConnection);
connect(this, SIGNAL(shutdownThread()), &signalWaiterEventLoop, SLOT(quit()), Qt::QueuedConnection);
connect(this, SIGNAL(dbChanged()), &signalWaiterEventLoop, SLOT(quit()), Qt::QueuedConnection);
while (!mShutdown) {
signalWaiterEventLoop.exec();
if (mShutdown) break;
/* ... useful payload */
foo();
/* ... another payload */
}
}
void WorkerThread::handleSuccess(const QByteArray & data) {
log(Q_FUNC_INFO, __LINE__, __FILE__);
QMutexLocker locker(&mutex);
/* processing data */
}
void WorkerThread::shutdown()
{
mShutdown = true;
emit shutdownThread();
}
对象在主线程中创建和初始化:
void SomeClass::init() {
/* ... */
mWorker = new WorkerThread();
connect(connect(mProtocol, SIGNAL(dataReceived(QByteArray)), mWorker, SLOT(processSuccess(QByteArray)),
Qt::QueuedConnection));
mWorker->start();
/* ... */
}
当从 run()
内部调用 foo()
时发生错误,锁定互斥锁,然后将流控制传递给 handleSuccess()
没有任何我看得见的原因,最后,handleSuccess()
试图锁定导致死锁的互斥锁。我会强调所有这一切都发生在一个线程中,我已经记录下来了。事实上,错误是稳定的,每次都出现在同一个地方。很明显我没有考虑到某些事情,但具体是什么?
更新我将 WorkerThread
重写为 Worker: public QObject
并且之前的 run()
变成了 public slot handleNewArrivals()
,它在线程的事件循环中被调用以响应信号。尽管如此,问题仍然存在:另一个槽正好在 handleNewArrivals()
的中间执行。中断的地方是稳定的,这里是(求evaluateTo()
):
bool hasContent = false;
QByteArray outData;
QBuffer inputBuffer(&data), outputBuffer(&outData);
inputBuffer.open(QIODevice::ReadOnly);
outputBuffer.open(QIODevice::WriteOnly|QIODevice::Append);
QXmlQuery xmlQuery;
xmlQuery.bindVariable("inputDocument", &inputBuffer);
xmlQuery.setQuery("doc($inputDocument)/commands//*");
QXmlSerializer serializer(xmlQuery, &outputBuffer);
log(Q_FUNC_INFO, __LINE__, __FILE__);
// the log line above appears, then after 1 ms the line
// from handleSuccess() appears successively.
xmlQuery.evaluateTo(&serializer);
// this line is never shown
log(Q_FUNC_INFO, __LINE__, __FILE__);
QXmlStreamReader xmlReader(outData);
while (!xmlReader.atEnd()) {
xmlReader.readNext();
if (xmlReader.tokenType() == QXmlStreamReader::Invalid) {
ufo::logT(this) << tr("Invalid token: %1").arg(xmlReader.errorString());
continue;
}
if (!xmlReader.isStartDocument() && !xmlReader.isEndDocument()) {
xmlWriterDb.writeCurrentToken(xmlReader);
hasContent = true;
}
}
ufo::logT(this) << tr("Selected data from payment, hasContent = %1").arg(hasContent?"true":"false");
inputBuffer.close();
outputBuffer.close();
QXmlQuery::evaluateTo 和 QXmlSerializer 有什么可以导致这样的跳转?似乎有异常或类似 unix 的信号(该软件在 Windows 下运行,mingw32)或其他东西,尽管包装 evaluateto()
或 try-catch 中的整个插槽没有给出任何结果。
最佳答案
我想你正被这种行为所困扰 documented for QXmlQuery
:
Event Handling
When QXmlQuery accesses resources (e.g., calling fn:doc() to load a file, or accessing a device via a bound variable), the event loop is used, which means events will be processed. To avoid processing events when QXmlQuery accesses resources, create your QXmlQuery instance in a separate thread.
如果 dataReceived()
信号已排队等待 handleSuccess()
槽,当 QXmlQuery
使用事件循环时,事件将是已处理。
关于c++ - 在 QThread::run 中间调用一个槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17030020/
我在QPushButton的最后一列中插入了QTableview。使用该按钮,我将使用按钮释放信号和插槽handlebutton(int)删除该特定行。 cpp代码: MainWindow::Main
它编译正常,但这是我运行程序时的错误消息: QObject::connect: Cannot queue arguments of type 'QVector' (Make sure 'QVector
我在 PyQt 中使用 for 循环 连接多个信号/槽。代码如下: # Connect Scan Callbacks for button in ['phase', 'etalon', 'mirror
我正在使用 Qt 创建一个 UI,有两个元素可能存在也可能不存在。此外,他们的 parent 也是不同的元素。但是,一个会影响另一个。 我应该如何以最佳方式构造信号/槽(或者我什至不应该使用该模式)?
我正在为这事兜圈子。就是无法理解信号和插槽。 只是在寻找某种机制,当我的 C++ 中出现信号时可以自动更新我的 UI。 示例: 我在 Qml 中有两个带有文本的标签:返回值的 _app.method。
我有两条路线呈现相同的组件,但来自 API 的数据不同。 该组件有一个名为 的子组件有一个 v-if检查特定插槽是否有内容的指令(因为如果它没有内容,我不希望该插槽显示)。 但是,在同一个父组件上可
我只是问当我的 html 位于 java-script 变量而不是 DOM 本身时如何使用 .each。 如果我有这样的 html: deze this dies 我能做到
基本上,想象一个宽度为 9(从 0 开始)的基于位置的区域 ╔════╦════╦════╦════╦════╦════╦════╦════╦════╗ ║ 0 ║ 1 ║ 2 ║ 3 ║
我想做一些非常简单的事情。单击切换按钮并在 QT 中获取消息框。 cpp: _show_hide_password = new QPushButton( "abc" ); _show_hide_pas
我有一个关于信号和槽的问题。在我的应用程序中,我想将来自一个对象的信号连接到 textEdit在对话框窗口中。我的信号发出 QString ;如果我违反封装(通过将 UI 公开而不是私有(privat
你好我来自java阵营,正在尝试做一个c++程序 我有一个名为 Manifest 的数组,它接收乘客对象 for (int i = 0; i Manifest . 例如 #include #incl
似乎为 Signal 类和插槽中调用的内容提供安全跨线程信号的唯一实现是 QT。 (也许我错了?)。 但是我不能在我做的项目中使用QT。那么我怎样才能从不同的线程(例如使用 Boost::signal
我将直接从示例开始: 在游戏中,有一个袋子供玩家用来存放他们的元素(元素的大小不一),袋子的大小也是可变的。 在一个 8x15 插槽的袋子中,我需要插入一个占用 2x2 插槽的元素,我可以搜索空间来实
PyQt 按钮事件可以以正常方式连接到函数,以便函数接收默认信号参数(在本例中为按钮选中状态): def connections(self): my_button.clicked.connec
访问类槽时,而不是写入 (defmethod get-name ((somebody person) (slot-value somebody 'name)) 是否可以使用点符号(又名 C++),即
我正在使用 vee-validate v3.0 进行验证并且设置很顺利,但现在我正在尝试设置我的元素的样式,但我似乎无法让它工作。我遵循了关于样式的非常简短的文档并编辑了 vee-validate 配
我尝试使用来自 https://wiki.qt.io/QThreads_general_usage 的方法与 moveToThread。一切安好。但是,如果我尝试将参数添加到完成的信号中,则会出现以下
我刚刚使用 iAds 和 adMob 在我的应用程序中实现了 adWhirl。一切都编译正确,adMob 工作完美,但我的 iAd 大小不正确。广告看起来尺寸合适,但实际上似乎被剪掉了。大约 1/4
我正在使用 python 和 PySide 开发 GUI 应用程序。我需要在单独的线程中运行长时间的背景任务。对于线程,我决定根据“正确”的方法使用 QThread,而不是从 if 进行子类化(参见
在用于编写 GUI 代码的 Qt 的 QML 语言中,QML 元素(如果我理解正确的话)在它们变得可见之前不会被实际创建。 (编辑: 听起来这些元素是在 QML 引擎加载它们时创建的,但看起来信号/槽
我是一名优秀的程序员,十分优秀!