第10篇 Qt实现安装向导对话框之代码布局篇(三)
1.源文件分段解说
1.1.主窗口类的构造函数
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("安装向导对话框");
this->setMinimumSize(300,200);
this->setMaximumSize(300,200);
beginbutton = new QPushButton("开始进行安装",this);
beginbutton->move(50,50);
QObject::connect(beginbutton,SIGNAL(clicked()),this,SLOT(setupWizard_show()));
}
其实没什么看的,就是设置一下标题,大小,还有给按钮分配内存大小,然后确定其位置,最后进行槽函数绑定。
1.2.创建安装向导对话框界面函数
void Widget::setupWizard_show()
{
this->setupWizard = new QWizard(this);
this->setupWizard->setWindowTitle("安装界面");
//设置风格和按钮名称
this->setupWizard->setButtonText(QWizard::BackButton,"上一步");
this->setupWizard->setButtonText(QWizard::NextButton,"下一步");
this->setupWizard->setButtonText(QWizard::FinishButton,"完成");
this->setupWizard->setButtonText(QWizard::CancelButton,"取消");
createPage_one();//创建第一个界面
createPage_two();//创建第二个界面
createPage_three();//创建第三个界面
createPage_four();//创建第四个界面
this->setupWizard->addPage(this->page_one);
this->setupWizard->addPage(this->page_two);
this->setupWizard->addPage(this->page_three);
this->setupWizard->addPage(this->page_four);
QObject::connect(this->setupWizard,SIGNAL(currentIdChanged(int)),this,SLOT(changePage(int)));
this->setupWizard->show();
this->setupWizard->button(QWizard::NextButton)->setEnabled(false);//显示之后将next按钮设置为不可点击,等待用户操作
}
第一部分是设置按钮的名称,QWizard::BackButton是表示上一步按钮的意思,但是要加上button函数才可以使用,button(QWizard::NextButton)相当于转换的意思吧。
在帮助文档里可以看到全部的按钮,如下
第二部分是创建界面,让后把页面加到对话框中。
这里值得说的是第三部分,关联槽和设置下一步按钮不可点击。
为了有一进去就让下一步按钮不可点击,我用了很多方法都不行,比如在show()之前加让它不可显示等都无效,直到在show()之后设置才有效,我觉得是因为,它显示的时候就把所有按钮都设置为可点击的,所以之前设置都无效。
第二点是向导对话框页面转换时会发出信号currentIdChanged(int),我们可以建一个槽来对这个信号做出相应,为什么有这个必要呢?第三个页面是你打开了页面进度条才开始动的,那么我们只需在这个槽函数里设置当切换到的页号是第三页时,就开始进行文件夹便利就可以了(注意页号是从0开始)。
1.3.第一个页面创建函数
void Widget::createPage_one()
{
this->page_one = new QWizardPage;
this->page_one->setSubTitle("安装协议");
QTextEdit *protocl = new QTextEdit;
QFile *file = new QFile;
file->setFileName("D:/Qt_project/WizardWork/installation.txt");
if(file->open(QIODevice::ReadOnly)){
QTextStream read(file);
protocl->setText(read.readAll());//读取所有内容并显示到文本框
file->close();
delete file;
}
else{
protocl->setText("安装协议书");
}
this->agree = new QCheckBox("我已阅读用户保护协议,并同意这份协议。");
QObject::connect(this->agree,SIGNAL(clicked()),this,SLOT(changeNextbutton()));
QGridLayout* glayout = new QGridLayout;
glayout->addWidget(protocl,0,0);
glayout->addWidget(agree,1,0);
this->page_one->setLayout(glayout);
}
这个函数还可以简单点,比如只在文本框里加一句话即可,我只是为了能在文本框里显示一篇文章,所以才用了文件的读取,所用到的方法注释了。第一个页面的布局方式为网格布局,就只有两个按钮,所以就设置了1:1,当然,文本框占比较大。
1.4.第二个页面创建函数
void Widget::createPage_two()
{
this->page_two = new QWizardPage;
this->page_two->setSubTitle("用户及兼容性设定");
QGroupBox* user = new QGroupBox("用户");
QHBoxLayout* hlayout = new QHBoxLayout;
QRadioButton* active_user = new QRadioButton("当前用户");
QRadioButton* all_users = new QRadioButton("所有用户");
hlayout->addWidget(active_user);
hlayout->addWidget(all_users);
user->setLayout(hlayout);
QGroupBox* compatibility = new QGroupBox("兼容性");
QVBoxLayout* vlayout = new QVBoxLayout;
QHBoxLayout* hlayout_one = new QHBoxLayout;
QHBoxLayout* hlayout_two = new QHBoxLayout;
QHBoxLayout* hlayout_three = new QHBoxLayout;
QCheckBox* checkbox_one = new QCheckBox("关联Doc、XLS、PPT");
QCheckBox* checkbox_two = new QCheckBox("关联PDF格式");
QCheckBox* checkbox_three = new QCheckBox("关联PNG、JPG等格式文件");
QCheckBox* checkbox_four = new QCheckBox("关联EPUBE");
location = new QLineEdit;
QPushButton* chosse_location = new QPushButton("安装位置");
QObject::connect(chosse_location,SIGNAL(clicked()),this,SLOT(chooseLocation()));
hlayout_one->addWidget(checkbox_one);
hlayout_one->addWidget(checkbox_two);
hlayout_two->addWidget(checkbox_three);
hlayout_two->addWidget(checkbox_four);
hlayout_three->addWidget(location);
hlayout_three->addWidget(chosse_location);
vlayout->addLayout(hlayout_one);
vlayout->addLayout(hlayout_two);
vlayout->addLayout(hlayout_three);
compatibility->setLayout(vlayout);
QGridLayout* glayout = new QGridLayout;
glayout->addWidget(user,0,0);
glayout->addWidget(compatibility,1,0);
this->page_two->setLayout(glayout);
}
第一部分是添加一个用户组并为其设置布局方式。只使用了一个水平布局。
第二部分是添加兼容性组,然后使用3个水平布局为其中的六个按钮布局,然后它的总体布局是垂直布局,
第三部分是这个页面的总体布局网格布局,将这两个组布局。
QPushButton* chosse_location = new QPushButton("安装位置");
QObject::connect(chosse_location,SIGNAL(clicked()),this,SLOT(chooseLocation()));
这个意思就是这个按钮被点击之后,相应的槽函数里会打开文件对话框,进行安装路径的选择。
1.5.第三个页面创建函数
void Widget::createPage_three()
{
this->page_three = new QWizardPage;
this->page_three->setSubTitle("安装进度");
QGridLayout* glayout = new QGridLayout;
glayout->addWidget(new QLabel("安装进度:"),0,0);
progress = new QProgressBar;
progress->setMaximum(100);progress->setMinimum(0);
progress->setValue(0);
this->progress_value = 0;
glayout->addWidget(progress,0,1);
glayout->addWidget(new QLabel("安装文件列表:"),1,0);
filelist = new QTextEdit;
glayout->addWidget(filelist,2,0,1,2);
this->page_three->setLayout(glayout);
}
第三个页面比较简单,只有两个控件,用网格布局或者垂直布局就可以。这个进度条的值并不需要通过信号来操作,只需在相关函数为其设置值就可以了。
1.6.代码布局小心得
(1)先画草图再写代码
如果对你要用代码布局的界面有点模糊,那就先在草稿纸上画一个大概的草图,这样代码布局的时候,就很清楚什么时侯用什么布局方式,可以达到事半功倍的效果。
(2)没有实际意义的按钮控件直接new方式添加即可
glayout->addWidget(new QLabel("安装文件列表:"),1,0);
比如这个,因为不需要对它进行任何的操作,所以直接这样加进去,就可以了。