0

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFileSystemModel>
#include <QThread>

#include <statusdialog.h>
#include <pbt.h>
#include <stdint.h>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    //void on_treeView_clicked(const QModelIndex &index);

    void onCustomContextMenuTV(const QPoint &point);

    void dirSize();

    void getSelectedTreeItemSize();
    void resultHandle(uint64_t);

signals:
    void sizeCalculation(uint64_t);

private:
    Ui::MainWindow *ui;
    QString sPath;
    QFileSystemModel *dirmodel;
    QFileSystemModel *filemodel;
    QAction *dirSizeAct;
    statusDialog statusdialog;
};

#endif // MAINWINDOW_H

pbt.h

   #ifndef STATUSDIALOG_H
#define STATUSDIALOG_H

#include <QDialog>

#include <stdint.h>

namespace Ui {
class statusDialog;
}

class statusDialog : public QDialog
{
    Q_OBJECT

public:
    explicit statusDialog(QWidget *parent = 0);
    ~statusDialog();
    void setProgressbarMax(uint64_t);

private slots:
    void on_pushButton_clicked();

private:
    Ui::statusDialog *ui;
};

#endif // STATUSDIALOG_H

statusdialog.h

#ifndef STATUSDIALOG_H
#define STATUSDIALOG_H

#include <QDialog>

#include <stdint.h>

namespace Ui {
class statusDialog;
}

class statusDialog : public QDialog
{
    Q_OBJECT

public:
    explicit statusDialog(QWidget *parent = 0);
    ~statusDialog();
    void setProgressbarMax(uint64_t);

private slots:
    void on_pushButton_clicked();

private:
    Ui::statusDialog *ui;
};

#endif // STATUSDIALOG_H

mainwindow.cpp

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

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

    sPath = "C:/";
    dirmodel = new QFileSystemModel(this);
    dirmodel->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs);
    dirmodel->setRootPath(sPath);
    ui->treeView->setModel(dirmodel);

    ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->treeView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onCustomContextMenuTV(const QPoint &)));

    connect(this,SIGNAL(sizeCalculation(uint64_t)),this,SLOT(resultHandle(uint64_t)));

}

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

void MainWindow::resultHandle(uint64_t t_size)
{
    statusdialog.setProgressbarMax(t_size);
}



void MainWindow::onCustomContextMenuTV(const QPoint &point)
{
    dirSizeAct = new QAction(tr("Size"), this);

    connect(dirSizeAct, SIGNAL(triggered()), this, SLOT(dirSize()));

    QMenu contextMenu(this);

    contextMenu.addAction(dirSizeAct);

    QModelIndex index = ui->treeView->indexAt(point);
    if (index.isValid()){
        contextMenu.exec(ui->treeView->mapToGlobal(point));
    }
}

void MainWindow::dirSize()
{
    pBT pbt;
    pbt.setFP(this->getSelectedTreeItemSize);
    QThread thread1;

    connect(&thread1,SIGNAL(started()),&pbt,SLOT(startThreadAction()));//Clone the object and it will not work, becouse it is QWidget

    pbt.moveToThread(&thread1);


    thread1.start();//Starts in the same thread

    statusdialog.setModal(true);
    statusdialog.exec();
}

void MainWindow::getSelectedTreeItemSize()
{
    QModelIndex index = ui->treeView->selectionModel()->selectedIndexes().takeFirst();
    QString dirPath = dirmodel->filePath(index);

    QDirIterator it(dirPath, QStringList() << "*.*", QDir::Files, QDirIterator::Subdirectories);
    uint64_t t_size = 0;

    while (it.hasNext()) {
        QFile myFile(it.next());
        if (myFile.open(QIODevice::ReadOnly)){
            t_size += myFile.size();
            myFile.close();
        }
    }

    emit sizeCalculation(t_size);
}

pbt.cpp

#include "pbt.h"

pBT::pBT(QObject *parent) : QObject(parent)
{

}

void pBT::startThreadAction()
{
      this->fp1();
}

void pBT::setFP(void (*fp1)())
{
    this->fp1 = fp1;
}

statusdialog.cpp

#include "statusdialog.h"
#include "ui_statusdialog.h"

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

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

void statusDialog::on_pushButton_clicked()
{
    this->close();
}

void statusDialog::setProgressbarMax(uint64_t size)
{
    ui->progressBar->setMaximum(size);
}

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

To see more info of what I am doing you can look this topic(It is all about prograssbar and threaded execution of job). Theoretically I whant to run a member function of mainwindow(which use member variables of mainwindow) into new thread(the function is not static) inside slot dirSize()(also member slot of the same class mainwindow), but it seems with QThread it is necessary to create new class(no matter if I will inherit QThread class or use moveToThread function of QObject) and run that class in new thread. If I use C++ thread.h the function I run must be static, nevermind I have tried to create pBT class in which I have function pointer fp1 and public slot startThreadedAction, but when try to buil this error occures:

C:\Users\niki\Documents\EPsimple\mainwindow.cpp:54: error: C3867: 'MainWindow::getSelectedTreeItemSize': function call missing argument list; use '&MainWindow::getSelectedTreeItemSize' to create a pointer to member

I don`t want to create function pointer to static function! How can I fix this?

Community
  • 1
  • 1
nicksona
  • 326
  • 2
  • 13
  • You can pass a non-static member method to [std::thread](http://www.cplusplus.com/reference/thread/thread/thread/). Look at the documentation again. – Mohamad Elghawi Nov 20 '15 at 13:51
  • If I put this code `std::thread t1(&MainWindow::getSelectedTreeItemSize); //Must be static function statusdialog.setModal(false); statusdialog.show(); t1.join();` into dirSize() slot I receive this error: `C:\Program Files\Microsoft Visual Studio 12.0\VC\include\functional:1149: error: C2064: term does not evaluate to a function taking 0 arguments class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments`, so it seems you can not do it!!! – nicksona Nov 20 '15 at 14:46
  • You have to pass the instance you want to call that method on to std::thread constructor. `std::thread t1(&MainWindow::getSelectedTreeItemSize, myInstance);` – Mohamad Elghawi Nov 20 '15 at 14:51
  • It is sleeping again the main thread. It starts new thread but actually when the function getSelectedTreeItemSize begin the main thread is forced to be sleeped. When I compare main thread id with getSelectedTreeItemSize id they are different, but the progressbar is stoping to respond until getSelectedTreeItemSize is finished. Theoretically it works, but actually it does not work like it should. I am passing `this` for myInstance. QThread does the same thing if I make it with `this`. – nicksona Nov 20 '15 at 16:11
  • Possible duplicate of [C++, function pointer to member function](http://stackoverflow.com/questions/2402579/c-function-pointer-to-member-function) – RobbieE Nov 20 '15 at 18:41
  • I must inclde maindialog.h into pbt.h in case to resolve MainWindow as class, but then from the code you can see I am including in mainwindow.h the pbt.h header file, so some errors begin to appear. We are talking here about two classes - in the one there is pointer to member function to function from the second class. – nicksona Nov 23 '15 at 10:39
  • In your link is showen how to create pointer to member function in the same class, but what happens if you want to create pointer to member function in class A which holds the adress of B's member function? You need to include B's header file into A's header file in case to resolve B as class. But what will hapen in my case when I create in B a member variable of type A? B is allready declared in A's header file so what will hapen - this error happens:`C:\Users\niki\Documents\EPsimple\pbt.cpp:10: error: C2064: term does not evaluate to a function taking 0 arguments` – nicksona Nov 23 '15 at 12:42

0 Answers0