C++ QT项目QThread和C++;线程限制

C++ QT项目QThread和C++;线程限制,c++,qt,function-pointers,C++,Qt,Function Pointers,main window.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 M

main window.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
   #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
#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.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);
}
#include "pbt.h"

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

}

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

void pBT::setFP(void (*fp1)())
{
    this->fp1 = fp1;
}
#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);
}
#include "mainwindow.h"
#include <QApplication>

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

    return a.exec();
}
main.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);
}
#include "pbt.h"

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

}

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

void pBT::setFP(void (*fp1)())
{
    this->fp1 = fp1;
}
#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);
}
#include "mainwindow.h"
#include <QApplication>

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

    return a.exec();
}
#包括“mainwindow.h”
#包括
int main(int argc,char*argv[])
{
质量保证申请a(argc、argv);
主窗口w;
w、 show();
返回a.exec();
}
要了解更多关于我正在做什么的信息,您可以查看主题(它都是关于prograssbar和作业的线程执行)。理论上,我不想在slot dirSize()内的新线程(该函数不是静态的)(也是同一类mainwindow的成员插槽)中运行mainwindow的成员函数(使用mainwindow的成员变量),但对于QThread,似乎有必要创建新类(无论我继承QQueToice还是使用QObjyQuoType函数),在新线程中运行该类。如果我使用C++线程。h,我运行的函数必须是静态的,不用介意,我已经尝试创建PBT类,在其中我有函数指针FP1和公共插槽StReStReDeDcAct,但是在试图解决这个错误时:

C:\Users\niki\Documents\EPsimple\mainwindow.cpp:54:错误:C3867: “MainWindow::getSelectedTreeItemSize”:函数调用缺少参数 列表;使用“&MainWindow::getSelectedTreeItemSize”创建指针 成员


我不想创建指向静态函数的函数指针!如何解决此问题?

您可以将非静态成员方法传递给。请再次查看文档。如果我将此代码放入
std::thread t1(&MainWindow::getSelectedTreeItemSize);//必须是静态函数statusdialog.setModal(false);statusdialog.show();t1.join();
into dirSize()插槽中我收到以下错误:
C:\Program Files\Microsoft Visual Studio 12.0\VC\include\functional:1149:错误:C2064:术语不计算为具有0个参数的函数类未定义“运算符()'或用户定义的转换运算符,指向具有适当数量参数的函数指针或函数引用
,因此您似乎无法执行!!!您必须将要调用该方法的实例传递给std::thread构造函数。
std::thread t1(&MainWindow::getSelectedTreeItemSize,myInstance);
它再次休眠主线程。它启动新线程,但实际上,当函数getSelectedTreeItemSize开始时,主线程被强制休眠。当我比较主线程id和getSelectedTreeItemSize id时,它们是不同的,但progressbar会停止响应,直到getSelectedTreeItemSize完成。理论上它可以工作,但实际上它不能正常工作。我正在为myInstance传递
这个
。如果我使用
这个
创建它,QThread也会做同样的事情。可能是