QObject使用技巧–控件功能类
使用Qt做过界面的同学可能会经常遇到一个问题,只要稍微把软件界面做的稍微复杂一点,UI所对应的cpp文件就写的非常的长,比如做一个组态软件,可能会有好几个cpp文件是直接超过2000行的,这会导致程序运行效率低下,而且非常不利于后期的程序的调整,毕竟从一个2000多行的代码中找到一个BUG往往是一件非常痛苦的事情。
做过UI的同学应该会遇到将多个控件按照一定的顺序进行排布,然后写到一个类里面,方便后面调用。但是你见过将控件的功能直接脱离UI界面的形式直接写到一个类里,之后只需要做个UI,连槽函数都不用就可以实现该联动的功能。这样可以分割代码,保证每一个cpp的程序保持在200行一下也可以实现一个非常复杂的功能。
实现功能
UI功能分割
相关说明
功能分割中最为麻烦的事情就是控件信号的问题,有很多做UI的软件都是因为在widget和dialog外是触发不了控件的信号的,这也就导致了如果要将程序分割就必须先将UI进行分割,到头来就是两种结果;要么UI界面是完整的,程序非常的臃肿,一般人看不懂;要么就是UI界面非常的破碎,代码成功分割,一般人还是看不懂。但是Qt控件的触发不一定需要widget或者dailog实现,而是在一个看不见的类QObject中就可以实现了,就可以实现UI界面上的完整性和功能的分割,最主要的是方便代码的理解以及后续的调试。
举个例子
以button,combobox和stackwidget三个控件为例实现一个简单的翻页的功能。
UI界面就长这个鬼样子
通过UI界面实现combobox选中的选项的变化实现stackwidget的翻页,button点击可以实现对应页面的关闭。
//stackedwidgetlist.h
#ifndef STACKEDWIDGETLIST_H
#define STACKEDWIDGETLIST_H
#include <QList>
#include <QStackedWidget>
#include <QComboBox>
#include <QStringList>
#include <QWidget>
#include <QObject>
#include <QPushButton>
#include "formpage.h"
class stackedWidgetList:public QObject //由控件button,combobox和stacketWidget组成实现stacketWidget的添加删除和翻页
{
Q_OBJECT
public:
stackedWidgetList(QObject *parent = nullptr); //初始化函数,使用该函数后需要额外绑定三个控件
stackedWidgetList(QPushButton **button,QComboBox **combobox,QStackedWidget **stackedwidget,QObject *parent = nullptr);
void insertwidget(FormPage **widget,QString name); //插入新的页面
void setComboBox(QComboBox **combobox); //绑定combobox
void setStackedWidget(QStackedWidget **widget);//的绑定stacketwidget
void setbutton(QPushButton **button); //绑定按钮
public slots:
void on_comboBox_currentIndexChanged(int index); //combobox的当前选项的修改,同时修改stacketwidget展示的页面,主要的翻页的手段
void on_button_clicked(); //按钮点击实现当前页面的删除
void on_stackedWidget_currentChanged(int arg1); //stacketwidget当前页面的修改,同时修改combobox的参数,一般情况下用不到
//此处需要实现的是绑定UI控件的绑定,UI控件默认是指针类型的,此处存储的必须是控件的指针的地址,所以此处使用的指针均为二重指针
private:
void deletewidget(); //删除当前页面
QStringList list; //用于存储ComboBox的内容
QList<FormPage*> listwidget; //用于存储stacketwidget中的多个绘图的页面
QStackedWidget *stackedwidget; //存储UI界面stacketwidget的地址
QComboBox *comboBox; //存储UI界面combobox的地址
QPushButton *button; //存储UI界面button的地址
};
#endif // STACKEDWIDGETLIST_H
#include "stackedwidgetlist.h"
#include <QDebug>
stackedWidgetList::stackedWidgetList(QObject *parent)
:QObject(parent)
{
button=nullptr;
stackedwidget=nullptr;
comboBox=nullptr;
}
stackedWidgetList::stackedWidgetList(QPushButton **button,QComboBox **combobox, QStackedWidget **stackedwidget, QObject *parent)
:QObject(parent)
{
setbutton(button);
setComboBox(combobox);
setStackedWidget(stackedwidget);
}
void stackedWidgetList::insertwidget(FormPage **widget, QString name)
{
if(stackedwidget!=nullptr&&comboBox!=nullptr)
{
stackedwidget->addWidget(*widget);
comboBox->addItem(name);
listwidget.append(*widget);
list.append(name);
comboBox->setCurrentIndex(comboBox->count()-1);
}
}
void stackedWidgetList::deletewidget()
{
if(stackedwidget!=nullptr&&comboBox!=nullptr)
{
listwidget.removeAt(stackedwidget->currentIndex());
stackedwidget->removeWidget(stackedwidget->currentWidget());
list.removeAt(stackedwidget->currentIndex());
comboBox->removeItem(stackedwidget->currentIndex());
for(int i=0;i<list.size();i++)
qDebug()<<list.at(i)<<endl;
}
}
void stackedWidgetList::setComboBox(QComboBox **comboBox)
{
this->comboBox=*comboBox;
if(this->comboBox!=nullptr)
connect(this->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(on_comboBox_currentIndexChanged(int)));
}
void stackedWidgetList::on_comboBox_currentIndexChanged(int index)
{
if(stackedwidget!=nullptr)
stackedwidget->setCurrentIndex(index+1);
}
void stackedWidgetList::on_button_clicked() //用于关闭当前的页面
{
if(comboBox!=nullptr&&stackedwidget!=nullptr) //首先需要分配comboBox和stacketWidget,否则按钮无效
{
if(comboBox->count()>=0&&stackedwidget->count()>=1)
{
deletewidget();
}
}
}
void stackedWidgetList::setStackedWidget(QStackedWidget **widget)
{
this->stackedwidget=*widget;
if(this->stackedwidget!=nullptr)
connect(this->stackedwidget,SIGNAL(currentChanged(int)),this,SLOT(on_stackedWidget_currentChanged(int)));
}
void stackedWidgetList::on_stackedWidget_currentChanged(int arg1)
{
if(comboBox!=nullptr)
{
comboBox->setCurrentIndex(arg1-1);
}
}
void stackedWidgetList::setbutton(QPushButton **button)
{
this->button=*button;
if(this->button!=nullptr)
connect(this->button,SIGNAL(clicked()),this,SLOT(on_button_clicked()));
}
初始化完成之后,配置了对应的控件就可以实现相应的功能了。注:控件拖拽是其他控件的功能。