C++ 如何从QWizardPage和access字段()运行QThread

C++ 如何从QWizardPage和access字段()运行QThread,c++,qt,qwidget,qwizard,qwizardpage,C++,Qt,Qwidget,Qwizard,Qwizardpage,我需要一些建议,以便从QThread访问QWizardPage中的字段(QString name)变量。我正在构建一个安装程序,我想在一个单独的线程中完成安装工作 我的目的: 当到达提交/安装页面时,我想执行代码进行“安装”,并用我的进度更新QWizardPage,直到完成 安装函数依赖于其他QWizardPages中的许多field()变量。因此,我尝试从一个QThread执行这个安装函数,该QThread是在我的QWizardPage的一个内部类中定义的。问题是,字段()-函数i是一个非静态

我需要一些建议,以便从
QThread
访问
QWizardPage
中的字段(
QString name
)变量。我正在构建一个安装程序,我想在一个单独的线程中完成安装工作

我的目的: 当到达提交/安装页面时,我想执行代码进行“安装”,并用我的进度更新
QWizardPage
,直到完成

安装函数依赖于其他
QWizardPages
中的许多
field()
变量。因此,我尝试从一个QThread执行这个安装函数,该QThread是在我的
QWizardPage
的一个内部类中定义的。问题是,
字段()
-函数i是一个非静态成员,因此无法工作。因此,我没有办法将安装功能与向导页面并行运行

我试过这样的方法:

InstallPage.h

class InstallPage : public QWizardPage
{
    Q_OBJECT
    class WorkerThread : public QThread
    {
        Q_OBJECT
        void run() override;
    };

public:
    InstallPage(QWidget *parent = 0);

private: 
    QLabel *lProgress;
    WorkerThread *installer;
    void install(); 
};


InstallPage.c

InstallPage::InstallPage(QWidget *parent)
    : QWizardPage(parent)
{
...
    installer = new WorkerThread(this);
    installer->start();
}

void InstallPage::WorkerThread::run()
{
    if(field("checkBox1").ToBool()) 
    {
         doStuff();
    }
}

//QT-Creator says at field("checkBox1"): 
//error: call to non-static member function without an object argument

我也愿意接受任何其他让我的安装程序工作的想法。可能有人知道一些我没有想到的事情。

另一种方法是创建一个工作线程(QObject),该工作线程位于执行繁重任务的另一个线程中,并通过信号通知该任务的状态:

#包括
类初始页:公共QWizardPage
{
公众:
初始页面(QWidget*parent=nullptr):QWizardPage(父)
{
QSpinBox*spinbox=新QSpinBox;
QLineEdit*lineedit=新的QLineEdit;
QVBoxLayout*lay=新的QVBoxLayout(本);
lay->addWidget(spinbox);
lay->addWidget(lineedit);
寄存器字段(“值1”,微调框);
注册表字段(“值2”,行编辑);
}
};
类InstallWorker:公共QObject
{
Q_对象
公众:
InstallWorker(QObject*parent=nullptr):QObject(parent)
{
}
公共Q_槽:
无效安装(int-param1、const-QString和param2)
{
Q_EMIT start();
对于(int i=0;i<100;i++){
qDebug()退出();
线程->等待();
}
无效初始化页(){
开始安装();
}
专用Q_插槽:
void start_install(){
int param1=字段(“值1”).toInt();;
QString param2=字段(“值2”).toString();
QMetaObject::invokeMethod(&worker,“install”,Qt::QueuedConnection,Q_ARG(int,param1),Q_ARG(QString,param2));
}
开始时无效(){
对于(QWizard::WizardButton,其中:{QWizard::BackButton,QWizard::NextButton,QWizard::CancelButton})
if(QAbstractButton*button=wizard()->按钮(哪个))
按钮->设置启用(错误);
}
void onFinished(){
对于(QWizard::WizardButton,其中:{QWizard::BackButton,QWizard::NextButton,QWizard::CancelButton})
if(QAbstractButton*button=wizard()->按钮(哪个))
按钮->设置启用(真);
向导()->next();
}
void onProgressChanged(int值){
进度条->设置值(值);
标签->设置数量(值);
}
私人:
安装工人;
QThread*线程;
QLabel*标签;
QProgressBar*progressbar;
};
类最终页:公共QWizardPage
{
公众:
最终页面(QWidget*parent=nullptr):QWizardPage(父级)
{
}
};
#包括“main.moc”
int main(int argc,char*argv[]){
QApplication应用程序(argc、argv);
QQ向导;
向导。添加页面(新初始页面);
向导。添加页面(新安装页面);
向导。添加页面(新的最终页面);
wizard.show();
返回app.exec();
}

就像eyllaesc建议的那样,反转依赖关系并创建一个单独的工作类,复制必要的信息。这也使同步变得更容易。我用一些字段对其进行了测试,这种方法效果很好。但我的问题是,我有许多字段,需要安装。在您的解决方案中,您传递了这些字段-值作为线程的参数。但是我需要大约20-30个参数,这似乎不是一个优雅的方法。有什么建议吗?@Tiger69它们是相同的类型吗?如果它们是相同的类型,则将其打包到一个容器中,这样您只需传递一个参数。如果它们不同,您可以将其转换为QVariant并使用容器作为索引爱德