Попробовал передать умный указатель std::unique_ptr
через сигнал/слот и получил ошибку из за удаленного конструктора копирования (unique_ptr(const unique_ptr&) = delete;
). Так можно ли использовать умный указатель std::unique_ptr
в сигнал/стол? UDP: нельзя!
Связный вопрос: Как передавать большие контейнеры между потоками?
Переделал класс под указатель std::shared_ptr<Data>
. Используя замечания @yrHeTaTeJlb, вызываю: Q_DECLARE_METATYPE(std::shared_ptr<Data>);
и qRegisterMetaType<std::shared_ptr<Data>>("shared_ptr<Data>");
. И все заработало.
Вывод qDebug():
Data();
finish
~Data();
mainwwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMap>
#include <memory>
class Data {
QMap<int, QString> _m; // большие
std::array<QString, 1024*1024> _a;
public:
Data() { qDebug() << "Data();"; }
~Data() { qDebug() << "~Data();"; }
void initData();
};
Q_DECLARE_METATYPE(std::shared_ptr<Data>);
class Worker : public QObject {
Q_OBJECT
std::shared_ptr<Data> _d;
public:
Worker() : QObject(), _d(std::make_shared<Data>()) { }
signals:
void finished(std::shared_ptr<Data> d);
public slots:
void process() { _d->initData(); emit finished(_d); }
};
class Controller : public QObject {
Q_OBJECT
std::shared_ptr<Data> _d;
public:
Controller(QObject *parent = nullptr) : QObject(parent) { }
void start();
signals:
void finished(std::shared_ptr<Data> d);
};
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
Controller _c;
std::shared_ptr<Data> _d;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QStandardItemModel>
#include <QThread>
void Data::initData() { /*some init code*/ }
void Controller::start() {
QThread *thr = new QThread;
Worker *w = new Worker;
w->moveToThread(thr);
connect(thr, &QThread::started, w, &Worker::process);
connect(w, &Worker::finished, this, &Controller::finished);
connect(w, &Worker::finished, thr, &QThread::quit);
connect(w, &Worker::finished, w, &Worker::deleteLater);
connect(thr, &QThread::finished, thr, &QThread::deleteLater);
thr->start();
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow) {
qRegisterMetaType<std::shared_ptr<Data>>("shared_ptr<Data>");
ui->setupUi(this);
connect(&_c, &Controller::finished, this, [this] (std::shared_ptr<Data> d) { qDebug() << "finish"; _d = d; });
_c.start();
}
MainWindow::~MainWindow() { delete ui; }
По умолчанию connect
выполянется с Qt::AutoConnection
.
Если сигнал передается между потоками Qt::AutoConnection
== Qt::QueuedConnection
Для того чтобы передавать объекты c Qt::QueuedConnection
их тип нужно зарегистрировать через QMetaType::qRegisterMetaType
.
Для этого тип нужно сначала объявить через Q_DECLARE_METATYPE
.
Q_DECLARE_METATYPE
требует чтобы у класса был конструктор копирования, а у std::unique_ptr
его нет.
Таким образом передать std::unique_ptr
через сигнал из потока в поток не получится.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Потребовалось написать пару простеньких скриптов на c++До этого когда-то писал в Visual Studio, сейчас сижу на linux(fedora 29), поэтому перешёл на gcc
Я использую библиотеку arborjs для построения графов (Я не смог найти установку через npm), как я могу использовать эту библиотеку у себя в проекте?
Я делаю рандом 3 статей из базы данных и добавить их в шаблон и данные из этого шаблона передать в другой шаблон с помощью include (короче: есть...