在软件开发中,需要对数据进行统计的时候,往往需要一个树形的表格窗口,并可以隐藏和移动。那么下面有三点小技术,可以实现它:Qt中的QTreeWidget的使用。Qt中QWidget的移动。Qt中窗口的自定义风格。
工具/原料
VS2013
Qt5.2
方法/步骤
1、Qt中的QTreeWidget和QTreeWidgetItem的使腩柽鬣盛用可以实现树形表。按照MVC设计,Qt中提倡用QTreeView,但是没有提供对应的Model,可以通过埠们萁猕自定义QStandardItemModel一起实现,但是比较复杂。不推荐使用。/***@brief初始化报表数据*/voidReportTree::initReportData(){ //根节点的数据项 QStringListitemStringlist; itemStringlist<<"AllEventS"<<"10000"<<"100%"<<"100%"; QTreeWidgetItem*rootItem=newQTreeWidgetItem(ui.treeWidget,itemStringlist); QPixmappixmap(10,10);//新建一个Pixmap图 pixmap.fill(QColor(Qt::black));//填充色 QIconicon(pixmap); rootItem->setIcon(0,icon);//设置图标 //根节点的孩子节点1 QStringListleafStringList1; leafStringList1<<"Gate1"<<"8000"<<"80%"<<"80%"; QTreeWidgetItem*leafItem1=newQTreeWidgetItem(rootItem,leafStringList1); pixmap.fill(QColor(Qt::red)); leafItem1->setIcon(0,pixmap); //根节点的孩子节点2 QStringListleafStringList2; leafStringList2<<"Gate2"<<"4000"<<"40%"<<"40%"; QTreeWidgetItem*leafItem2=newQTreeWidgetItem(rootItem,leafStringList2); pixmap.fill(QColor(Qt::green)); leafItem2->setIcon(0,pixmap); //根节点的孩子节点3 QStringListleafStringList3; leafStringList3<<"Gate3"<<"2000"<<"20%"<<"20%"; QTreeWidgetItem*leafItem3=newQTreeWidgetItem(rootItem,leafStringList3); pixmap.fill(QColor(Qt::blue)); leafItem3->setIcon(0,pixmap); //节点3的孩子节点1_in_3 QStringListleafStringList1_In_3; leafStringList1_In_3<<"Gate1_in_3"<<"1000"<<"50%"<<"10%"; QTreeWidgetItem*leafItem1_in_3=newQTreeWidgetItem(leafItem3,leafStringList1_In_3); pixmap.fill(QColor(Qt::gray)); leafItem1_in_3->setIcon(0,pixmap); //给节点3添加孩子节点 leafItem3->addChild(leafItem1_in_3); //节点3的孩子节点2_in_3 QStringListleafStringList2_In_3; leafStringList2_In_3<<"Gate2_in_3"<<"500"<<"40%"<<"2%"; QTreeWidgetItem*leafItem2_in_3=newQTreeWidgetItem(leafItem3,leafStringList2_In_3); pixmap.fill(QColor(Qt::darkCyan)); leafItem2_in_3->setIcon(0,pixmap); leafItem3->addChild(leafItem2_in_3); //给根节点添加孩子节点 rootItem->addChild(leafItem1); rootItem->addChild(leafItem2); rootItem->addChild(leafItem3);}
2、Qt中QWidget的移动。只需要重写一个QWidget的子类,将如下三个事件重载。即可实现在标题栏附近移动窗口。但是当前窗口的父窗口指定,而且当前窗口背景是透明的,需要QSS自定义颜色。//指定当前窗口要显示的父类窗口 reportTree=newReportTree(this); reportTree->setVisible(false);voidReportTree::mousePressEvent(QMouseEvent*event){ //只能是鼠标左键移动和改变大小 if(event->button()==Qt::LeftButton) { if(event->y()>33)//控制在标题栏内,才可以拖动窗口 { event->ignore(); return; } mouse_press=true; } //窗口移动距离 move_point=event->globalPos()-pos();}voidReportTree::mouseReleaseEvent(QMouseEvent*){ mouse_press=false;}voidReportTree::mouseMoveEvent(QMouseEvent*event){ if(event->y()<=33)//控制在标题栏内,才可以拖动窗口 { setCursor(Qt::SizeAllCursor); } else { setCursor(Qt::ArrowCursor); } //移动窗口 if(mouse_press) { QPointmove_pos=event->globalPos(); move(move_pos-move_point); }}
3、Qt中窗口的自定义风格Qt本身的标题栏和VC一样风格,比较挫。当你在陕择遑握父窗口内显示QWidget,它会自动隐藏标烙疋艘烯题栏和边框。所以只需要自定义一个标题栏即可。至于关闭按钮的效果,通过QSS是无法实现的。只需要用自定义一个PushButton即可,实现正常,hover,pressed三种状态。PushButton::PushButton(QWidget*parent) :QPushButton(parent){ status=NORMAL; mouse_press=false;}PushButton::~PushButton(){}voidPushButton::setPicName(QStringpic_name){ this->pic_name=pic_name; setFixedSize(QPixmap(pic_name).size());}voidPushButton::enterEvent(QEvent*){ status=ENTER; update();}voidPushButton::mousePressEvent(QMouseEvent*event){ //若点击鼠标左键 if(event->button()==Qt::LeftButton) { mouse_press=true; status=PRESS; update(); }}voidPushButton::mouseReleaseEvent(QMouseEvent*event){ //若点击鼠标左键 if(mouse_press&&this->rect().contains(event->pos())) { mouse_press=false; status=ENTER; update(); emitclicked(); }}voidPushButton::mouseMoveEvent(QMouseEvent*event){ //控制在标题栏内,才可以拖动窗口 setCursor(Qt::ArrowCursor);}voidPushButton::leaveEvent(QEvent*){ status=NORMAL; update();}voidPushButton::paintEvent(QPaintEvent*){ QPainterpainter(this); QPixmappixmap; switch(status) { caseNORMAL: { pixmap.load(pic_name); break; } caseENTER: { pixmap.load(pic_name+QString("_hover")); break; } casePRESS: { pixmap.load(pic_name+QString("_pressed")); break; } caseNOSTATUS: { pixmap.load(pic_name); break; } default: pixmap.load(pic_name); } painter.drawPixmap(rect(),pixmap);}
4、作者:柳北风儿博客