- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我的 Qt 5.7(在 Windows 10 上)应用程序中遇到了一个奇怪的错误,并且找不到导致这种行为的常见罪魁祸首:
完整的错误信息是
QObject::moveToThread: Current thread (0x2afcca68) is not the object's thread (0x34f4acc8). Cannot move to target thread (0x34f4adc8)
QObject::setParent: Cannot set parent, new parent is in a different thread
这也是我的代码:
main.cpp
#include <QApplication>
#include <QQuickItem>
#include "CustomQuickWidget.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
const QUrl source = QUrl(QLatin1String("qrc:/main"));
CustomQuickWidget widget(source);
return app.exec();
}
main(main.qml 的别名):
// You can put any random QML content in this case really as long as it doesn't create a window since the CustomQuickWidget does that.
Rectangle {
id: window
visible: true
width: 600
height: 480
}
CustomQuickWidget.cpp
#include "CustomQuickWidget.h"
#include <QQuickItem>
CustomQuickWidget::CustomQuickWidget(const QUrl &source, QWidget *parent) : QQuickWidget(source, parent) {
// Setup the recognizer
this->airWheelRecognizer = new QAirWheelGestureRecognizer();
this->airWheelType = QGestureRecognizer::registerRecognizer(airWheelRecognizer);
// and turn on grabbing for all the supported gestures
grabGesture(airWheelType);
grabGesture(Qt::SwipeGesture);
grabGesture(Qt::TapGesture);
// Create thread and device worker
this->deviceThread = new QThread(this);
this->deviceWorker = new DeviceMapper(this, Q_NULLPTR); // NOTE: this here is NOT for parent. The constructor's signature for this class is: DeviceMapper(QObject* receiver, QList<Qt::GestureType>* gestureIDs, QObject* parent = Q_NULLPTR)
this->deviceWorker->init();
// Create timer that will trigger the data retrieval slot upon timeout
this->timer = new QTimer();
this->timer->setTimerType(Qt::PreciseTimer);
this->timer->setInterval(5);
// Move timer and device mapper to other thread
this->timer->moveToThread(this->deviceThread);
this->deviceWorker->moveToThread(this->deviceThread); // FIXME For unknown reason: QObject::moveToThread: Current thread (...) is not the object's thread. Cannot move to target thread
// Connect widget, timer and device mapper
createConnections();
// Run thread
this->deviceThread->start();
// Connect device and start data retrieval
QTimer::singleShot(0, this->deviceWorker, &(this->deviceWorker->slotToggleConnection));
QTimer::singleShot(0, this->deviceWorker, &(this->deviceWorker->slotToggleRun));
this->show();
}
CustomQuickWidget::~CustomQuickWidget()
{
if (this->deviceThread) {
this->deviceThread->quit();
this->deviceThread->wait();
}
}
void CustomQuickWidget::createConnections()
{
connect(this->timer, SIGNAL(timeout()),
this->deviceWorker, SLOT(slotRetrieveData()));
connect(this->deviceThread, SIGNAL(started()),
this->timer, SLOT(start()));
connect(this->deviceThread, SIGNAL(finished()),
this->deviceWorker, SLOT(deleteLater()));
connect(this->deviceThread, SIGNAL(finished()),
this->deviceThread, SLOT(deleteLater()));
}
bool CustomQuickWidget::event(QEvent* event) {
if (event->type() == QEvent::Gesture) {
bool res = gestureEvent(static_cast<QGestureEvent*>(event)); // Not important so not included as code here
return res;
}
return QWidget::event(event);
}
如您所见,我这里有一个典型的工作线程。我已确保我的工作人员(此处为 DeviceMapper
)没有父级。它也在我的小部件内实例化(QThread
也被创建)但与计时器一起移动到线程。
现在除了标题中的明显问题外,我还必须提及以下内容:
this->timer->moveToThread(this->deviceThread);
时没有报错我的其他应用程序和这个应用程序之间的唯一区别是 QQuickWidget
(而不是 QWidget
)和 QML
的使用。我对 QML
很陌生,这也是我的第一个 QQuickWidget
,所以我可能会遗漏一些需要“激活”的明显设置。
我也添加了
cout << this->deviceWorker->thread()->currentThreadId() << endl;
cout << this->thread()->currentThreadId() << endl;
就在 this->deviceWorker->moveToThread(this->deviceThread);
之前,我得到了
0x18b0
0x18b0
这意味着在 moveToThread(...)
之前,我的对象属于实例化 QThread
的同一个线程。在 moveToThread(...)
之后打印线程 ID 返回相同的结果,但这是预期的,因为未能将对象正确移动到另一个线程。
更新:
只有在 Release模式下构建时才会出现错误消息,但是无论构建类型如何,我的错误仍然存在。
最佳答案
我已经设法通过查明问题发生的时间来解决我的问题。
在上周结束时,我正在编写的应用程序突然开始工作,所以尽管我很困扰为什么之前发生的所有事情,但我还是顺其自然。我既没有更改库的代码(除了我的代码中的一些注释显然不会影响代码本身),也没有更改我的 QML
应用程序的 C++
代码。我所更改的只是我的 QML
,但实际上与下面的 C++
代码无关。我唯一改变的是构建类型。但是我上周并没有真正注意到这一点。
昨天我开始了一个新项目。在第一次运行后,我遇到了同样的问题。这让我抓狂。所以我开始分析我的代码(@Kuba Ober,对不起,伙计,但是发布完整的代码甚至库的一小部分是不可能的,否则我会这样做(即使它有几百行实际代码(不包括评论和空行之类的东西))。我检查并仔细检查了父子关系,但找不到任何可以给我哪怕是一个小提示的东西,什么时候以及为什么会发生这种情况。我还分析了堆栈以尽我所能,但一切都是徒劳的。
然后我突然想到...我在上面提到过,我以前的项目在更改其构建类型 后突然开始工作。在我的处境中,这确实是万恶之源。我将我的库添加到我的项目中的方法(不包括与库一起属于同一 subdir
项目的初始库)是在我的新项目的根目录中创建一个名为 libs
并将相关内容复制到其中。现在,在我完成我的库并进行一些测试后,我显然决定切换到发布版本。但是,我将 release
模式下的库构建复制到 debug
模式下构建的项目。因此,在多次重建并在各处复制库之后,我发现混合使用该库的应用程序的构建类型和库本身会导致此问题。
我知道混合构建类型是一个坏主意,而且我通常不会那样做,但这次我只是忘记了,完全是个意外。当具有 X 构建类型的应用程序和具有 Y 构建类型的库混合使用时,我不知道内部发生了什么,但我的结果是我在此线程中发布的错误。
感谢大家的帮助。我从你的评论中学到了很多东西!尽管在我的情况下不需要调试,但我很感激你。 :)
关于c++ - Qt 无法将目标移动到线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38850077/
我将 Bootstrap 与 css 和 java 脚本结合使用。在不影响前端代码的情况下,我真的很难在css中绘制这个背景。在许多问题中,人们将宽度和高度设置为 0%。但是由于我的导航栏,我不能使用
我正在用 c 编写一个程序来读取文件的内容。代码如下: #include void main() { char line[90]; while(scanf("%79[^\
我想使用 javascript 获取矩阵数组的所有对 Angular 线。假设输入输出如下: input = [ [1,2,3], [4,5,6], [7,8,9], ] output =
可以用pdfmake绘制lines,circles和other shapes吗?如果是,是否有documentation或样本?我想用jsPDF替换pdfmake。 最佳答案 是的,有可能。 pdfm
我有一个小svg小部件,其目的是显示角度列表(参见图片)。 现在,角度是线元素,仅具有笔触,没有填充。但是现在我想使用一种“内部填充”颜色和一种“笔触/边框”颜色。我猜想line元素不能解决这个问题,
我正在为带有三角对象的 3D 场景编写一个非常基本的光线转换器,一切都工作正常,直到我决定尝试从场景原点 (0/0/0) 以外的点转换光线。 但是,当我将光线原点更改为 (0/1/0) 时,相交测试突
这个问题已经有答案了: Why do people write "#!/usr/bin/env python" on the first line of a Python script? (22 个回
如何使用大约 50 个星号 * 并使用 for 循环绘制一条水平线?当我尝试这样做时,结果是垂直(而不是水平)列出 50 个星号。 public void drawAstline() { f
这是一个让球以对角线方式下降的 UI,但球保持静止;线程似乎无法正常工作。你能告诉我如何让球移动吗? 请下载一个球并更改目录,以便程序可以找到您的球的分配位置。没有必要下载足球场,但如果您愿意,也可以
我在我的一个项目中使用 Jmeter 和 Ant,当我们生成报告时,它会在报告中显示 URL、#Samples、失败、成功率、平均时间、最短时间、最长时间。 我也想在报告中包含 90% 的时间线。 现
我有一个不寻常的问题,希望有人能帮助我。我想用 Canvas (android) 画一条 Swing 或波浪线,但我不知道该怎么做。它将成为蝌蚪的尾部,所以理想情况下我希望它的形状更像三角形,一端更大
这个问题已经有答案了: Checking Collision of Shapes with JavaFX (1 个回答) 已关闭 8 年前。 我正在使用 JavaFx 8 库。 我的任务很简单:我想检
如何按编号的百分比拆分文件。行数? 假设我想将我的文件分成 3 个部分(60%/20%/20% 部分),我可以手动执行此操作,-_-: $ wc -l brown.txt 57339 brown.tx
我正在努力实现这样的目标: 但这就是我设法做到的。 你能帮我实现预期的结果吗? 更新: 如果我删除 bootstrap.css 依赖项,问题就会消失。我怎样才能让它与 Bootstrap 一起工作?
我目前正在构建一个网站,但遇到了 transform: scale 的问题。我有一个按钮,当用户将鼠标悬停在它上面时,会发生两件事: 背景以对 Angular 线“扫过” 按钮标签颜色改变 按钮稍微变
我需要使用直线和仿射变换绘制大量数据点的图形(缩放图形以适合 View )。 目前,我正在使用 NSBezierPath,但我认为它效率很低(因为点在绘制之前被复制到贝塞尔路径)。通过将我的数据切割成
我正在使用基于 SVM 分类的 HOG 特征检测器。我可以成功提取车牌,但提取的车牌除了车牌号外还有一些不必要的像素/线。我的图像处理流程如下: 在灰度图像上应用 HOG 检测器 裁剪检测到的区域 调
我有以下图片: 我想填充它的轮廓(即我想在这张图片中填充线条)。 我尝试了形态学闭合,但使用大小为 3x3 的矩形内核和 10 迭代并没有填满整个边界。我还尝试了一个 21x21 内核和 1 迭代,但
我必须找到一种算法,可以找到两组数组之间的交集总数,而其中一个数组已排序。 举个例子,我们有这两个数组,我们向相应的数字画直线。 这两个数组为我们提供了总共 7 个交集。 有什么样的算法可以帮助我解决
简单地说 - 我想使用透视投影从近裁剪平面绘制一条射线/线到远裁剪平面。我有我认为是使用各种 OpenGL/图形编程指南中描述的方法通过单击鼠标生成的正确标准化的世界坐标。 我遇到的问题是我的光线似乎
我是一名优秀的程序员,十分优秀!