Qt:可移动的树形数据报表
1、Qt中的QTreeWidget和QTreeWidgetItem 的使用可以实现树形表。
按照MVC设计,Qt中提倡用QTreeView,但是没有提供对应的Model,可以通过自定义QStandardItemModel一起实现,但是比较复杂。不推荐使用。
/**
* @brief 初始化报表数据
*/
void ReportTree::initReportData()
{
//根节点的数据项
QStringList itemStringlist;
itemStringlist << "All EventS" <<"10000" << "100%" << "100%";
QTreeWidgetItem *rootItem = new QTreeWidgetItem(ui.treeWidget, itemStringlist);
QPixmap pixmap(10,10);//新建一个Pixmap图
pixmap.fill(QColor(Qt::black));//填充色
QIcon icon(pixmap);
rootItem->setIcon(0, icon);//设置图标
//根节点的孩子节点1
QStringList leafStringList1;
leafStringList1 << "Gate1" << "8000"<<"80%"<<"80%";
QTreeWidgetItem *leafItem1 = new QTreeWidgetItem(rootItem, leafStringList1);
pixmap.fill(QColor(Qt::red));
leafItem1->setIcon(0, pixmap);
//根节点的孩子节点2
QStringList leafStringList2;
leafStringList2 << "Gate2" << "4000" << "40%" << "40%";
QTreeWidgetItem *leafItem2 = new QTreeWidgetItem(rootItem, leafStringList2);
pixmap.fill(QColor(Qt::green));
leafItem2->setIcon(0, pixmap);
//根节点的孩子节点3
QStringList leafStringList3;
leafStringList3 << "Gate3" << "2000" << "20%" << "20%";
QTreeWidgetItem *leafItem3 = new QTreeWidgetItem(rootItem, leafStringList3);
pixmap.fill(QColor(Qt::blue));
leafItem3->setIcon(0, pixmap);
//节点3的孩子节点1_in_3
QStringList leafStringList1_In_3;
leafStringList1_In_3 << "Gate1_in_3" << "1000" << "50%" << "10%";
QTreeWidgetItem *leafItem1_in_3 = new QTreeWidgetItem(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
QStringList leafStringList2_In_3;
leafStringList2_In_3 << "Gate2_in_3" << "500" << "40%" << "2%";
QTreeWidgetItem *leafItem2_in_3 = new QTreeWidgetItem(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 = new ReportTree(this);
reportTree->setVisible(false);
void ReportTree::mousePressEvent(QMouseEvent *event)
{
//只能是鼠标左键移动和改变大小
if (event->button() == Qt::LeftButton)
{
if (event->y() > 33)//控制在标题栏内,才可以拖动窗口
{
event->ignore();
return;
}
mouse_press = true;
}
//窗口移动距离
move_point = event->globalPos() - pos();
}
void ReportTree::mouseReleaseEvent(QMouseEvent *)
{
mouse_press = false;
}
void ReportTree::mouseMoveEvent(QMouseEvent *event)
{
if (event->y() <= 33)//控制在标题栏内,才可以拖动窗口
{
setCursor(Qt::SizeAllCursor);
}
else
{
setCursor(Qt::ArrowCursor);
}
//移动窗口
if (mouse_press)
{
QPoint move_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()
{
}
void PushButton::setPicName(QString pic_name)
{
this->pic_name = pic_name;
setFixedSize(QPixmap(pic_name).size());
}
void PushButton::enterEvent(QEvent *)
{
status = ENTER;
update();
}
void PushButton::mousePressEvent(QMouseEvent *event)
{
//若点击鼠标左键
if(event->button() == Qt::LeftButton)
{
mouse_press = true;
status = PRESS;
update();
}
}
void PushButton::mouseReleaseEvent(QMouseEvent *event)
{
//若点击鼠标左键
if(mouse_press && this->rect().contains(event->pos()))
{
mouse_press = false;
status = ENTER;
update();
emit clicked();
}
}
void PushButton::mouseMoveEvent(QMouseEvent *event)
{
//控制在标题栏内,才可以拖动窗口
setCursor(Qt::ArrowCursor);
}
void PushButton::leaveEvent(QEvent *)
{
status = NORMAL;
update();
}
void PushButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap pixmap;
switch(status)
{
case NORMAL:
{
pixmap.load(pic_name);
break;
}
case ENTER:
{
pixmap.load(pic_name + QString("_hover"));
break;
}
case PRESS:
{
pixmap.load(pic_name + QString("_pressed"));
break;
}
case NOSTATUS:
{
pixmap.load(pic_name);
break;
}
default:
pixmap.load(pic_name);
}
painter.drawPixmap(rect(),pixmap);
}

4、作者:柳北风儿 博客