QSplitter(分离器或分隔符)

QSplitter(分离器或分隔符)

本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)

若对C++语法不熟悉,建议参阅《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可确保读者彻底弄懂C++的原理,彻底解惑C++,使其知其然更知其所以然。此书是一本全面了解C++不可多得的案头必备图书。

5.4.1 QSplitter类(分离器)

QSplitter类继承自QFrame类,也就是说该类是一个带有边框的可视部件。QSplitter类实现了分离器,分离器用于分离两个部件(原理见图5-39),用户可通过拖动部件之间的分界线来调整子部件的大小。
在这里插入图片描述
QSplitter的实现原理(见图5-39)与QBoxLayout布局的原理类似,即QSplitter把子部件以水平或垂直的方式添加到QSplitter中,只不过在这些子部件之间多了一条分界线,另外QSplitter继承自QFrmae,因此QSplitter是有边框的。而且它可以作为容器和窗口使用,但不推荐使用QPushButton pb(&splitter)的形式向QSplitter中添加子部件。
动态调整是指移动分界线时部件大小随之动态的改变。若不是动态调整的,则在移动分界线时部件大小不会改变,当完成分界线的移动时(即松开鼠标时),部件的大小才改变。
分离器中的子部件会随着分离器大小的改变而改变,当分离器大小改变时,分离器会重新分配空间,以使其所有子部件的相对大小保持相同的比例不变。
子部件的大小策略对分离器不起作用,分离器会把子部件填充满整个空间,即使子部件的大小策略设置为Fixed,仍会被拉伸。
1、分界线(QSplitterHandle类)
 分界线是由QSplitterHandle类实现的,QSplitter类本身不实现分界线。因此QSplitterHandle是一个部件,而QSplitter是另一个部件,这是两个部件,只不过这两个部件通过Qt的内部设计让他们关联在一起,产生了一定的联系。
 QSplitter的分界线默认有可能是看不见的(因为颜色与QSplitter背景色相同,所以看不见),因此要使分界线可见,需设置分界线的背景色。
 分界线的索引从0开始编号,分界线的数量与子部件的数量一样多。但索引为0的分界线始终是隐藏的。对于垂直分离器,索引为0的子部件上方的分界线索引为0,对于水平分离器(对于从左到右的语言),则索引为0的子部件左侧的分界线的索引为0,对于从右到左的语言,则索引为0的子部件右侧的分界线的索引为0。

2、使用QSplitter的步骤如下:
①、创建一个QSplitter。
②、使用addWidget()函数把子部件添加到QSplitter中。
③、代码如下:
在这里插入图片描述

3、QSplitter类的属性
在这里插入图片描述
4、QSplitter类的函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

示例5.18:QSplitter类(分离器)的使用

#include<QtWidgets>
int main(int argc, char *argv[]){    QApplication a(argc,argv);
    QWidget w;							QSplitter *ps=new QSplitter(Qt::Vertical);
    QPushButton *pb=new QPushButton("AAA");    QPushButton *pb1=new QPushButton("BBB");
    QPushButton *pb2=new QPushButton("CCC");
    QPushButton *pb3=new QPushButton("DDD",ps);   //不推荐此种方式向分离器中添加子部件
    pb1->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);	//大小策略不起作用
    pb->setMaximumSize(175,55);  							//最大最小值仍可限制子部件
    ps->addWidget(pb);    	ps->addWidget(pb1);	    ps->addWidget(pb2);
    ps->addWidget(pb3);  			//pb3已在分离器ps中,因此把pb3移至新位置
//设置分离器的边框
ps->setFrameShadow(QFrame::Raised);	ps->setFrameShape(QFrame::Box);	ps->setLineWidth(5);
    ps->setChildrenCollapsible(0);  	//子部件不可折叠
    ps->setOpaqueResize(1);   		//动态调整子部件
    ps->setStretchFactor(0,1);  		//设置拉伸因子,以调整初始显示时各子部件间的位置
    ps->setStretchFactor(1,2);    ps->setStretchFactor(2,2);
ps->setHandleWidth(5);    		//设置分界线的宽度
//设置分界线的背景色为蓝色,若不设置背景色,则分界线可能会不可见
    ps->setStyleSheet("QSplitter::handle{background-color: blue}");  	//样式表见第13章
    QVBoxLayout *pv=new QVBoxLayout;     pv->addWidget(ps);    		//把分离器ps添加到布局pv中
    w.setLayout(pv);	    w.resize(300,200);        w.show();    return a.exec();  }

运行结果及说明见图5-41
在这里插入图片描述
示例5.19:QSplitter综合示例(设计的界要和要求见图5-42)
//m.h文件的内容

#ifndef M_H
#define M_H
#include<QtWidgets>
#include <iostream>
using namespace std;
class B:public QSplitter{    Q_OBJECT
public:    static QString ddd;   //用于存储来自行编辑器输入的文本
    		B(Qt::Orientation o=Qt::Horizontal,QWidget* p=0):QSplitter(o,p){}
 public slots:
    void f(){ int j=0;        	//计数器
    		int i[3]={0};   		//用于存储从文本ddd中提出取来的数字。
    		QString s1=ddd;
    		while(!s1.isEmpty()){  s1=ddd.section(",",j,j);  	//提取文本中以","分隔的数字
    			if(j>2)return;     		//如果文本中的数字个数大于等于3个,则退出函数。
    			i[j]=s1.toInt();   		//把提取出来的数字赋值给数组i。
   			j++;}
    moveSplitter(i[0],i[1]);  } };    /*使用文本中输入的前两个数字设置分界线的位置。注意:这个函数是受保护的,若索引(第二个参数)超出范围,该函数会产生错误。*/
class C:public QWidget{    Q_OBJECT
public:	B *ps;           			//分离器
    QLineEdit *pe,*pe1;	    QLabel *pl,*pl1;    QPushButton *pb,*pb1,*pb2,*pb3,*pb4,*pb5;
    QByteArray b;    				//用于保存和恢复分离器的状态
C(QWidget* p=0):QWidget(p){    	//构造函数
    		ps=new B(Qt::Vertical);    	pl=new QLabel("EnterSize");   pl1=new QLabel("pose,index");
    		pe=new QLineEdit;   		pe1=new QLineEdit;
    		pe->setClearButtonEnabled(1);   pe1->setClearButtonEnabled(1);//显示行编辑器的清除按钮
pb=new QPushButton("AAA");	pb1=new QPushButton("BBB");   	pb2=new QPushButton("CCC");
pb3=new QPushButton("save");		    	pb4=new QPushButton("restore");
//布置分离器ps的子部件。
    		ps->addWidget(pb);    ps->addWidget(pb1);    ps->addWidget(pb2);
//设置分离器的边框及其他属性
    ps->setFrameShadow(QFrame::Raised);    ps->setFrameShape(QFrame::Box);
    ps->setLineWidth(5);					ps->setChildrenCollapsible(0); 
    //设置分离器的边框样式后,重新设置分离器的大小策略,否则分离器可能不会扩展。
ps->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
//设置分界线的背景色为蓝色,若不设置背景色,则分界线可能会不可见
    ps->setHandleWidth(5);   ps->setStyleSheet("QSplitter::handle{background-color: blue}");
//布置主窗口的子部件
    QVBoxLayout *pv=new QVBoxLayout;   //主窗口使用的主布局
    QFormLayout *pf=new QFormLayout;   	pf->addRow(pl,pe);    	pf->addRow(pl1,pe1);
    QHBoxLayout *ph=new QHBoxLayout;    	ph->addWidget(pb3);    	ph->addWidget(pb4);
//把布局pf,ph和分离器,添加到主布局中
    pv->addLayout(ph);    pv->addLayout(pf);    pv->addWidget(ps);    setLayout(pv);
    QObject::connect(pe, &QLineEdit::returnPressed, this, &C::fSet);
    QObject::connect(pb3, &QPushButton::clicked, this, &C::fSave);
    QObject::connect(pb4, &QPushButton::clicked, this, &C::fRestore);
    QObject::connect(pe1, &QLineEdit::returnPressed, this, &C::f);
    QObject::connect(pe1, &QLineEdit::returnPressed, ps, &B::f);		}  //构造函数结束
public slots:
void fSet(){      				//使用setSizes函数设置分离器各子部件的大小
    		QString ss=pe->text();  	//获取行编辑器pe的文本
    		int j=0;   				//计数器
    		QString s1=ss;
   		QList<int> b;   			//使用列表存储从文本ss中提取出来的数字
    		while(!s1.isEmpty()){
    			s1=ss.section(",",j,j);	//提取以","分隔的数字。
    			b.append(s1.toInt());  	//把提取出来的数字追到加列表b的末尾。
    			j++;		}
    		if(b.size()<=3)   return;   //如果输入的数字个数少于3个,则退出函数。
    		ps->setSizes(b);  } 		//使用列表b设置各分离器子部件的位置
void fSave(){ b=ps->saveState();    cout<<"save OK"<<endl;}		//保存分离器的状态。
void fRestore(){    ps->restoreState(b);	}    				//恢复分离器的状态
    void f(){  B::ddd=pe1->text();   }};	//把行编辑器pe1输入的内容存储到静态变量B::ddd中
#endif // M_H

//m.cpp文件的内容

#include "m.h"
QString B::ddd;  //初始化静态变量,注意:静态变量不应在头文件中初始化,否则会出现重定义错误。
int main(int argc, char *argv[]){    QApplication a(argc,argv);
    		C w;    w.resize(300,500);        w.show();    return a.exec();  }

运行结果及说明见图5-42
在这里插入图片描述
示例5.20:QSplitter的嵌套使用(实现的界面如图5-43所示)
#include

int main(int argc, char *argv[]){    
QApplication a(argc,argv);
QWidget w;    
QSplitter *ps=new QSplitter(Qt::Vertical);
QSplitter *ps1=new QSplitter(Qt::Vertical);
QSplitter *ps2=new QSplitter(Qt::Horizontal);
QTextEdit *pt=new QTextEdit;    
QTextEdit *pt1=new QTextEdit;
QTextEdit *pt2=new QTextEdit;
//设置分界线的背景色及边框
    ps->setHandleWidth(1);   ps->setStyleSheet("QSplitter::handle{background-color: blue}");
    ps2->setFrameShadow(QFrame::Raised);    ps2->setFrameShape(QFrame::Box);
    ps2->setLineWidth(2);	    ps2->setHandleWidth(5);
    ps2->setStyleSheet("QSplitter::handle{background-color: red}");
//布局子部件
    ps->addWidget(pt);    	ps->addWidget(pt1);    	ps1->addWidget(pt2);
    ps2->addWidget(ps1);    	ps2->addWidget(ps);
    QHBoxLayout *ph=new QHBoxLayout;    ph->addWidget(ps2);    w.setLayout(ph);
    w.resize(300,200);        w.show();    return a.exec();  }

在这里插入图片描述

5.4.2 QSplitterHandle类(分界线)

QSplitterHandle类继承自QWidget,该类主要用于实现QSplitter(分离器)的分界线,因此,通常与分离器一起使用。该类的规则请参阅QSplitter类。
QSplitterHandle类比较简单,只有如下几个公有函数
在这里插入图片描述

示例5.21:QSplitterHandle(分界线)的使用
//m.h文件的内容

#ifndef M_H
#define M_H
#include<QtWidgets>
class B:public QSplitter{    Q_OBJECT
public:    B(Qt::Orientation o=Qt::Horizontal,QWidget* p=0):QSplitter(o,p){}
public slots:
    QSplitterHandle *createHandle(){    //重新实现该虚函数,创建自定义的分界线
        QSplitterHandle *ph=new QSplitterHandle(orientation(),this);   //自定义的分界线
        ph->setMinimumSize(22,22);             //设计分界线的最小大小
        return ph;            }}; 			//返回自定义的分界线
#endif // M_H

//m.cpp文件的内容

#include "m.h"
int main(int argc, char *argv[]){    QApplication a(argc,argv);
    QWidget w;    B *ps=new B(Qt::Vertical);
    QPushButton *pb=new QPushButton("AAA");    QPushButton *pb1=new QPushButton("BBB");
    QPushButton *pb2=new QPushButton("CCC");
    ps->addWidget(pb);    ps->addWidget(pb1);    ps->addWidget(pb2);
    ps->setStyleSheet("QSplitter::handle{background-color: red}");  //设置分界线的颜色(红色)
QHBoxLayout *ph=new QHBoxLayout;    ph->addWidget(ps);    w.setLayout(ph);
    w.resize(300,200);    w.show();    return a.exec();    }

运行结果及说明见图5-44

在这里插入图片描述

展开阅读全文

没有更多推荐了,返回首页