qDebug()<<"主线程地址: " 显示出?????
时间: 2023-08-09 19:06:47 浏览: 53
如果你在主线程中使用 `qDebug()` 输出主线程的地址,可能会得到一些奇怪的结果。这是因为 `qDebug()` 是一个用于输出调试信息的函数,并不直接支持输出指针或地址。如果你想输出主线程的地址,你可以使用 `qintptr` 类型来转换指针,然后再使用 `qDebug()` 输出。以下是一个示例:
```cpp
qintptr threadAddress = reinterpret_cast<qintptr>(QThread::currentThreadId());
qDebug() << "主线程地址:" << threadAddress;
```
这样,你应该能够正确输出主线程的地址。请注意,这只适用于 Qt 框架中的主线程。对于其他框架或平台,请查阅相应的文档来获取正确的方法。
相关问题
OPENCV QT线程池示例,主线程采集摄像头视频,两个子线程显示图像和保存图像
好的,这里给您提供一个 OpenCV 和 Qt 的线程池示例,主线程采集摄像头视频,两个子线程分别显示图像和保存图像:
```cpp
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <opencv2/opencv.hpp>
using namespace cv;
class DisplayThread : public QThread
{
Q_OBJECT
public:
DisplayThread(QObject *parent = nullptr) : QThread(parent) {}
signals:
void imageReady(QImage image);
protected:
void run() override
{
VideoCapture cap(0);
if (!cap.isOpened()) {
qDebug() << "Cannot open camera";
return;
}
while (true) {
Mat frame;
cap >> frame;
if (frame.empty()) {
qDebug() << "Capture frame failed";
break;
}
QImage image = QImage(frame.data, frame.cols, frame.rows, QImage::Format_RGB888).rgbSwapped();
emit imageReady(image);
}
}
};
class SaveThread : public QThread
{
Q_OBJECT
public:
SaveThread(QObject *parent = nullptr) : QThread(parent) {}
void setSavePath(const QString &path)
{
m_savePath = path;
}
signals:
void saveDone(const QString &path);
protected:
void run() override
{
VideoCapture cap(0);
if (!cap.isOpened()) {
qDebug() << "Cannot open camera";
return;
}
int i = 0;
while (true) {
Mat frame;
cap >> frame;
if (frame.empty()) {
qDebug() << "Capture frame failed";
break;
}
QString fileName = QString("%1/frame_%2.jpg").arg(m_savePath).arg(i++);
imwrite(fileName.toStdString(), frame);
emit saveDone(fileName);
}
}
private:
QString m_savePath;
};
class VideoPlayer : public QObject
{
Q_OBJECT
public:
VideoPlayer(QObject *parent = nullptr) : QObject(parent)
{
m_displayThread = new DisplayThread(this);
m_saveThread = new SaveThread(this);
connect(m_displayThread, &DisplayThread::imageReady, this, &VideoPlayer::onImageReady);
connect(m_saveThread, &SaveThread::saveDone, this, &VideoPlayer::onSaveDone);
m_displayThread->start();
m_saveThread->start();
}
~VideoPlayer()
{
m_displayThread->quit();
m_displayThread->wait();
m_saveThread->quit();
m_saveThread->wait();
}
signals:
void imageReady(QImage image);
void saveDone(const QString &path);
private slots:
void onImageReady(QImage image)
{
emit imageReady(image);
}
void onSaveDone(const QString &path)
{
emit saveDone(path);
}
private:
DisplayThread *m_displayThread;
SaveThread *m_saveThread;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
VideoPlayer player;
QObject::connect(&player, &VideoPlayer::imageReady, [](QImage image){
// 显示图像
});
QObject::connect(&player, &VideoPlayer::saveDone, [](const QString &path){
// 保存图像
});
return a.exec();
}
#include "main.moc"
```
在这个示例中,我们创建了一个 `VideoPlayer` 类,它包含了一个 `DisplayThread` 和一个 `SaveThread` 线程。`DisplayThread` 用于采集摄像头视频,并将每一帧图像通过信号 `imageReady` 发送给主线程,主线程再将图像显示出来。`SaveThread` 用于采集摄像头视频,并将每一帧图像保存到硬盘上,每保存一帧图像就通过信号 `saveDone` 发送给主线程,主线程再进行相应的处理。
在 `main` 函数中,我们创建了一个 `VideoPlayer` 对象,并连接了两个信号 `imageReady` 和 `saveDone`。当 `DisplayThread` 发送 `imageReady` 信号时,我们就在主线程中显示图像;当 `SaveThread` 发送 `saveDone` 信号时,我们就在主线程中进行相应的处理,比如更新 UI 界面等。
c++ qt 利用moveToThread的方式创建一个多线程的例子,具体创建两个子线程,一个子线程生成10个随机数,另一个子线程接收10个随机数并排序,主线程分别显示排序之前和排序之后的随机数
以下是一个简单的示例代码,其中第一个子线程用于生成随机数,第二个子线程用于排序:
```c++
#include <QCoreApplication>
#include <QObject>
#include <QThread>
#include <QDebug>
#include <QVector>
class RandWorker : public QObject
{
Q_OBJECT
public:
explicit RandWorker(QObject *parent = nullptr) : QObject(parent) {}
public slots:
void generateRand() {
QVector<int> nums;
qsrand(QTime::currentTime().msec());
for (int i = 0; i < 10; ++i) {
nums.append(qrand() % 100);
}
emit generated(nums);
}
signals:
void generated(QVector<int>);
};
class SortWorker : public QObject
{
Q_OBJECT
public:
explicit SortWorker(QObject *parent = nullptr) : QObject(parent) {}
public slots:
void sortRand(QVector<int> nums) {
std::sort(nums.begin(), nums.end());
emit sorted(nums);
}
signals:
void sorted(QVector<int>);
};
class MainThread : public QObject
{
Q_OBJECT
public:
explicit MainThread(QObject *parent = nullptr) : QObject(parent) {}
public slots:
void showGenerated(QVector<int> nums) {
qDebug() << "Generated numbers:" << nums;
sortWorker->moveToThread(sortThread);
connect(randWorker, &RandWorker::generated, sortWorker, &SortWorker::sortRand, Qt::QueuedConnection);
connect(sortWorker, &SortWorker::sorted, this, &MainThread::showSorted, Qt::QueuedConnection);
randThread->quit();
randThread->wait();
sortThread->start();
}
void showSorted(QVector<int> nums) {
qDebug() << "Sorted numbers:" << nums;
sortThread->quit();
sortThread->wait();
qApp->quit();
}
signals:
void start();
private:
QThread *randThread = new QThread(this);
QThread *sortThread = new QThread(this);
RandWorker *randWorker = new RandWorker();
SortWorker *sortWorker = new SortWorker();
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MainThread mainThread;
mainThread.start();
mainThread.randWorker->moveToThread(mainThread.randThread);
QObject::connect(mainThread.randThread, &QThread::started, mainThread.randWorker, &RandWorker::generateRand, Qt::QueuedConnection);
QObject::connect(mainThread.randWorker, &RandWorker::generated, &mainThread, &MainThread::showGenerated, Qt::QueuedConnection);
mainThread.randThread->start();
return a.exec();
}
#include "main.moc"
```
在 `RandWorker` 类中,我们定义了 `generateRand()` 方法来生成 10 个随机数,并使用 `generated(QVector<int>)` 信号将其发送到主线程。在 `SortWorker` 类中,我们定义了 `sortRand(QVector<int>)` 方法来对随机数进行排序,并使用 `sorted(QVector<int>)` 信号将排序后的结果发送到主线程。在 `MainThread` 类中,我们定义了 `showGenerated(QVector<int>)` 方法来接收生成的随机数,将 `sortWorker` 移动到 `sortThread` 中,并将 `generated(QVector<int>)` 信号连接到 `sortRand(QVector<int>)` 方法。然后,我们退出 `randThread` 并等待其完成,启动 `sortThread`。在 `showSorted(QVector<int>)` 方法中,我们接收排序后的结果,输出它们,并退出 `sortThread` 和应用程序。最后,在 `main()` 函数中,我们启动 `randThread` 并进入应用程序的事件循环。
请注意,我们使用了 `Qt::QueuedConnection` 参数来确保从不同线程发出的信号和槽都在主线程中执行。此外,我们在 `MainThread` 类的构造函数中创建了 `randThread`、`sortThread`、`randWorker` 和 `sortWorker` 对象,并将它们添加到 `MainThread` 对象的父项中,以确保它们在 `MainThread` 对象被销毁时也被销毁。