c++multithreadingqtqstringlistmodel

QStringListModel * as a parameter of a signal giving me the error "...attempting to reference deleted function"?


I wrote this small test programm so I understand QT's Signals & Slots, aswell as Multithreading, better.

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QString>
#include <QStringListModel>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    Ui::MainWindow *ui;
public slots:
    void change_stats(QString &msg);
    void insert_list(QStringListModel *model);
private:
};
#endif // MAINWINDOW_H

worker.h

#ifndef WORKER_H
#define WORKER_H
#include "mainwindow.h"

#include <QObject>
#include <QString>

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(MainWindow &mw);

signals:
    QString statsmsg(QString);
    QStringListModel heremodel(QStringListModel*);
public slots:
    void wip_list();
    void wip_status();
private:
    MainWindow *w;
};

#endif // WORKER_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::change_stats(QString &msg)
{
    ui->statusbar->showMessage(msg);
}

void MainWindow::insert_list(QStringListModel *model)
{
    ui->listView->setSelectionMode(QListView::SingleSelection);
    ui->listView->setModel(model);
}

worker.h

#include "worker.h"
#include <QThread>
#include <QStringListModel>
#include <vector>
#include <chrono>
#include "ui_mainwindow.h"
#include <sstream>

Worker::Worker(MainWindow &mw)
{
    w = &mw;
    QThread *thread = new QThread;
    this->moveToThread(thread);
    connect(thread, SIGNAL(started()), this, SLOT(wip_status));
    connect(w->ui->pushButton, SIGNAL(clicked()), this, SLOT(wip_list()));
    connect(this, SIGNAL(heremodel(QStringListModel*)), w, SLOT(insert_list(QStringListModel*)));
    connect(this, SIGNAL(statsmsg(QString)), w, SLOT(change_stats(QString)));
    thread->start();
}

void Worker::wip_list(){

    QStringListModel *model = new QStringListModel();
    QStringList list;
    std::string row = "row nr.";
    for(int i = 1; i <= 10; i++){
        std::stringstream rows;
        rows << row << i;
        list << QString::fromStdString(rows.str());
    }
    model->setStringList(list);
    emit heremodel(model);
}

void Worker::wip_status(){
    std::vector<QString> connecting = {"Connecting", "Connecting.", "Connecting..", "Connecting..."};
    QString msg = "Connecting";
    std::chrono::milliseconds interval = std::chrono::milliseconds(300);
    while(1){
        for(int i = 0; i <= 3; i++){
            msg = connecting[i];
            emit statsmsg(msg);
            std::this_thread::sleep_for(interval);
        }
    }
}

main.cpp

#include "worker.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    Worker worker(w);
    w.show();
    return a.exec();
}

But when I run Debug it gives me this error: error: C2280: 'QStringListModel &QStringListModel::operator =(const QStringListModel &)': attempting to reference a deleted function

I'm new here so please don't be too harsh, also if you spot something wrong not relevant to the question, please tell me. Thanks in advance for replying to my question!


Solution

  • Your heremodel signal is declared to return a QStringListModel by value...

    QStringListModel heremodel(QStringListModel*);
    

    Hence the error as QObject is non-copyable.

    Change the signal signature to...

    void heremodel(QStringListModel*);