void Widget::createPage_four()
{
this->page_four = new QWizardPage;
this->page_four->setSubTitle("激活");
QGridLayout* glayout = new QGridLayout;
glayout->addWidget(new QLabel("激活方式:"),0,0);
activation_mode = new QComboBox;
activation_mode->addItem("序列号");
activation_mode->addItem("登陆账号");
QObject::connect(activation_mode,SIGNAL(currentIndexChanged(int)),this,SLOT(changeActivation(int)));
glayout->addWidget(activation_mode,0,1);
this->enter_widget = new QListWidget(this->page_four);
QGridLayout* enterlayout = new QGridLayout;
enterlayout->addWidget(new QLabel("用户名"),0,0);
QLineEdit* user = new QLineEdit;
user->setMaxLength(15);
enterlayout->addWidget(user,0,1);
enterlayout->addWidget(new QLabel("密码"),1,0);
QLineEdit* password = new QLineEdit;
password->setMaxLength(15);
password->setEchoMode(QLineEdit::Password);
enterlayout->addWidget(password,1,1);
this->enter_widget->setLayout(enterlayout);
this->serialnumber_widget = new QListWidget(this->page_four);
QGridLayout* serlayout = new QGridLayout;
serlayout->addWidget(new QLabel("序列号"),0,0);
QLineEdit* number = new QLineEdit;
number->setMaxLength(15);
number->setInputMask(">AAAAA-AAAAA-AAAAA-AAAAA;#");
serlayout->addWidget(number,0,1);
this->serialnumber_widget->setLayout(serlayout);
this->activate_widget = new QStackedWidget(this->page_four);
glayout->addWidget(this->activate_widget,1,0,1,2);
this->activate_widget->addWidget(this->serialnumber_widget);
this->activate_widget->addWidget(this->enter_widget);
glayout->addWidget(new QPushButton("激活"),2,0);
QFrame* vline = new QFrame(this->page_four);
vline->setFrameShape(QFrame::HLine);
vline->setFrameShadow(QFrame::Sunken);
glayout->addWidget(vline,3,0,1,2);
glayout->addWidget(new QCheckBox("跳过"),4,1);
this->page_four->setLayout(glayout);
}
代码长了不好说,把图放在这里看吧,第一部分就是最顶端的激活方式和序列号和登录账号的设置,和对QComboBox按钮的槽函数链接,以达到切换时的界面切换效果。关于StackedWidget的使用可以去搜索一下,有很多文章,这里就不赘述了。
第二部分是对登录账号方式界面的布局,第三是序列号方式的布局,为了方便我都用的是网格布局方式。
number->setInputMask(">AAAAA-AAAAA-AAAAA-AAAAA;#");这句话的意思是设置输入方式为序列号,还有很多种输入方式,需要了解的到帮助文档查一下就可以了。
第四部分是把布局好的两个界面加入QStackedWidget中,以便可以通过它来进行页面切换。
第五部分是加入一条线,我其实很奇怪啊,当时我不知道这条线怎么加,去UI哪里拖动之后看到线条对应的类名是QLine,但是用代码添加不对,然后去问老师,他让我去看.ui文件对应的头文件,最后才看到原来是通过QFram来实现的,细节之后再说。
void Widget::findFile(QString filepath)
{
QDir dir(filepath);
if (!dir.exists()) {
return ;
}
//取到所有的文件和文件名,但是去掉.和..的文件夹(这是QT默认有的)
dir.setFilter(QDir::Dirs|QDir::Files|QDir::NoDotAndDotDot);
//文件夹优先
dir.setSorting(QDir::DirsFirst);
//转化成一个list
QFileInfoList list = dir.entryInfoList();
if(list.size()< 1 ) {
return ;
}
int i=0;
//递归算法的核心部分
do{
this->progress_value++;
this->progress->setValue(this->progress_value);
QThread::msleep(300);
QFileInfo fileInfo = list.at(i);
this->filelist->insertPlainText(fileInfo.absoluteFilePath() + '\n');//将路径显示在安装文件列表中
//如果是文件夹,递归
bool bisDir = fileInfo.isDir();
if(bisDir) {
findFile(fileInfo.filePath());
}
i++;
} while(i < list.size());
}
这个是复制比人的代码改动的,博客里有很多文章。可以看到是通过递归实现的,因为如果是文件夹的画我们要进去便利,不是文件夹那就输出即可,我们设置一个变量progress_value表示进度条的值,每便利一次就加1,然后通过线程类来暂停300毫秒,以便达到肉眼能看到进度条变化的情况,注意时间不能太小,不然看不到,嗖的一下就变成100了。然后将当前遍历到的文件或者文件夹路经加到文本框里,注意加上换行符,当然还有另一种加入方式。append(const QString &text)
(1)QObject::connect(this->agree,SIGNAL(clicked()),this,SLOT(changeNextbutton()));
void Widget::changeNextbutton()
{
if(!this->agree->isChecked()){
this->setupWizard->button(QWizard::NextButton)->setEnabled(false);
}
else{
this->setupWizard->button(QWizard::NextButton)->setEnabled(true);
}
}
如果按钮没有被勾选,则设置安装向导对话框的下一步按钮为不可点击,否则设置为可以点击。
(2)QObject::connect(chosse_location,SIGNAL(clicked()),this,SLOT(chooseLocation()));
void Widget::chooseLocation()
{
QString locationname = QFileDialog::getExistingDirectory(this,"选择安装路径","/");
location->setText(locationname);
}
按钮被点击后打开文件对话框,这里有很多学问,我也不了解,这个是搜来的。
(3)QObject::connect(activation_mode,SIGNAL(currentIndexChanged(int)),this,SLOT(changeActivation(int)));
void Widget::changeActivation(int index)
{
if(0 == index){
this->activate_widget->setCurrentWidget(this->serialnumber_widget);
}
else{
this->activate_widget->setCurrentWidget(this->enter_widget);
}
}
当前勾选的位置改变,作出响应,只有序列号和登录账号两种方式,所以index是0和1,0就显示序列号界面,1就显示登陆账号页面。
(4)QObject::connect(this->setupWizard,SIGNAL(currentIdChanged(int)),this,SLOT(changePage(int)));
void Widget::changePage(int id)
{
if(id == 2){
findFile(this->location->text());
this->progress->setValue(this->progress->maximum());
}
}
对应的是向导对话框的页面转换消息,发出的消息中的int变量的值是,切换到的页面的id(0开始),2是第三页,到第三页时进行文件夹遍历。
#include "widget.h"
#include "ui_widget.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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()));
}
Widget::~Widget()
{
delete ui;
}
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按钮设置为不可点击,等待用户操作
}
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);
}
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);
}
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);
}
void Widget::createPage_four()
{
this->page_four = new QWizardPage;
this->page_four->setSubTitle("激活");
QGridLayout* glayout = new QGridLayout;
glayout->addWidget(new QLabel("激活方式:"),0,0);
activation_mode = new QComboBox;
activation_mode->addItem("序列号");
activation_mode->addItem("登陆账号");
QObject::connect(activation_mode,SIGNAL(currentIndexChanged(int)),this,SLOT(changeActivation(int)));
glayout->addWidget(activation_mode,0,1);
this->enter_widget = new QListWidget(this->page_four);
QGridLayout* enterlayout = new QGridLayout;
enterlayout->addWidget(new QLabel("用户名"),0,0);
QLineEdit* user = new QLineEdit;
user->setMaxLength(15);
enterlayout->addWidget(user,0,1);
enterlayout->addWidget(new QLabel("密码"),1,0);
QLineEdit* password = new QLineEdit;
password->setMaxLength(15);
password->setEchoMode(QLineEdit::Password);
enterlayout->addWidget(password,1,1);
this->enter_widget->setLayout(enterlayout);
this->serialnumber_widget = new QListWidget(this->page_four);
QGridLayout* serlayout = new QGridLayout;
serlayout->addWidget(new QLabel("序列号"),0,0);
QLineEdit* number = new QLineEdit;
number->setMaxLength(15);
number->setInputMask(">AAAAA-AAAAA-AAAAA-AAAAA;#");
serlayout->addWidget(number,0,1);
this->serialnumber_widget->setLayout(serlayout);
this->activate_widget = new QStackedWidget(this->page_four);
glayout->addWidget(this->activate_widget,1,0,1,2);
this->activate_widget->addWidget(this->serialnumber_widget);
this->activate_widget->addWidget(this->enter_widget);
glayout->addWidget(new QPushButton("激活"),2,0);
QFrame* vline = new QFrame(this->page_four);
vline->setFrameShape(QFrame::HLine);
vline->setFrameShadow(QFrame::Sunken);
glayout->addWidget(vline,3,0,1,2);
glayout->addWidget(new QCheckBox("跳过"),4,1);
this->page_four->setLayout(glayout);
}
void Widget::findFile(QString filepath)
{
QDir dir(filepath);
if (!dir.exists()) {
return ;
}
//取到所有的文件和文件名,但是去掉.和..的文件夹(这是QT默认有的)
dir.setFilter(QDir::Dirs|QDir::Files|QDir::NoDotAndDotDot);
//文件夹优先
dir.setSorting(QDir::DirsFirst);
//转化成一个list
QFileInfoList list = dir.entryInfoList();
if(list.size()< 1 ) {
return ;
}
int i=0;
//递归算法的核心部分
do{
this->progress_value++;
this->progress->setValue(this->progress_value);
QThread::msleep(300);
QFileInfo fileInfo = list.at(i);
this->filelist->insertPlainText(fileInfo.absoluteFilePath() + '\n');//将路径显示在安装文件列表中
//如果是文件夹,递归
bool bisDir = fileInfo.isDir();
if(bisDir) {
findFile(fileInfo.filePath());
}
i++;
} while(i < list.size());
}
void Widget::changeNextbutton()
{
if(!this->agree->isChecked()){
this->setupWizard->button(QWizard::NextButton)->setEnabled(false);
}
else{
this->setupWizard->button(QWizard::NextButton)->setEnabled(true);
}
}
void Widget::chooseLocation()
{
QString locationname = QFileDialog::getExistingDirectory(this,"选择安装路径","/");
location->setText(locationname);
}
void Widget::changeActivation(int index)
{
if(0 == index){
this->activate_widget->setCurrentWidget(this->serialnumber_widget);
}
else{
this->activate_widget->setCurrentWidget(this->enter_widget);
}
}
void Widget::changePage(int id)
{
if(id == 2){
findFile(this->location->text());
this->progress->setValue(this->progress->maximum());
}
}
结束了,非代码布局再说。