奉贤网站开发,怎么做淘宝客个人网站,自己建网站还是淘宝,网站建设项目需求分析流程介绍
此文章记录QTreeWidget的重写进度#xff0c;暂时停滞使用#xff0c;重写了QTreeWidget的拖拽功能#xff0c;和绘制功能#xff0c;自定义了数据结构#xff0c;增加复制#xff0c;粘贴#xff0c;删除#xff0c;准备实现动态刷新数据支持千万数据动态刷新暂时停滞使用重写了QTreeWidget的拖拽功能和绘制功能自定义了数据结构增加复制粘贴删除准备实现动态刷新数据支持千万数据动态刷新重写了部分代码重写了滑块拖拽但是有bug。
效果展示 实现功能
实现了自定义节点类来存储数据。item采用Label来实现富文本显示(数据量大不建议使用)。重写了QTreeWidget拖拽滚动绘制。拖拽实现了节点与节点之间的互相拖拽仅移动。实现了节点的递归遍历查找插入删除。实现了滚动刷新数据大量数据也不卡但是滚动条刷新数据稍微复杂未完成且有bug。
代码
#ifndef MYTREEWIDGET_H
#define MYTREEWIDGET_H#include QWidget
#include QtWidgets
#include QDebugclass MyTreeWidgetItem;
class TreeNode;
class MyLabel;// 自定义节点类
class TreeNode {
public:QString nodeText;QString nodeItemTest;QListTreeNode* children;TreeNode* parent nullptr;MyTreeWidgetItem* item;// 重载运算符以判断nodeText是否相等bool operator(const TreeNode other) const {return nodeText other.nodeText;}
};class MyTreeWidgetItem :public QTreeWidgetItem
{
public:MyTreeWidgetItem();void setNodeText(QString str);QString getNodeText();QString m_Text;MyLabel* m_Label;int indexOfChild(QTreeWidgetItem *child){int childCount this-childCount();for (int i 0; i childCount; i) {if (this-child(i) child) {return i;}}return -1;}
};class MyLabel : public QLabel
{Q_OBJECT
public:MyLabel(QString text, QWidget *parent nullptr);bool m_IsSelect false;bool m_IsLeave true;QString enterStyle;QString leaveStyle;QString selectStyle;
protected:bool eventFilter(QObject *watched, QEvent *event);
};class MyTreeWidget : public QTreeWidget
{Q_OBJECT
public:MyTreeWidget(QWidget *parent nullptr);QListTreeNode* m_ListData;void wait(int ms); //等待// 删除具有特定文本的节点及其子节点bool deleteNodeByText(const QString targetText) {for (int i 0; i m_ListData.size(); i) {TreeNode* node m_ListData.at(i);if (node-nodeText targetText) {// 找到目标节点删除其子节点qDeleteAll(node-children);delete node;m_ListData.removeAt(i);return true; // 成功删除节点}}return false; // 未找到匹配的节点}//删除指定父节点下的子节点bool deleteChildNode(TreeNode* node, const QString nodeText) {for (int i 0; i node-children.size(); i) {if (node-children.at(i)-nodeText nodeText) {node-children.removeAt(i);return true;}}return false;}//根据nodeText递归查找该对象TreeNode* recursiveFindNodeByText(const QString targetText, TreeNode* currentNode) {if (currentNode-nodeText targetText) {return currentNode;}for (TreeNode* child : currentNode-children) {TreeNode* result recursiveFindNodeByText(targetText, child);if (result) {return result;}}return nullptr; // 未找到匹配的节点}//根据nodeText递归查找该对象TreeNode* findNodeByText(const QString targetText, const QListTreeNode* nodeList) {for (TreeNode* node : nodeList) {TreeNode* result recursiveFindNodeByText(targetText, node);if (result) {return result;}}return nullptr; // 未找到匹配的节点}//插入字节点 包括数据更新TreeNode* insertChileItem(TreeNode* parentNode, int row, QString itemText);//追加子节点TreeNode* appendChileItem(TreeNode* parentNode, QString itemText);//插入顶部节点TreeNode* insertTopItem(int row, QString itemText, bool isInster true);//void updateItem(int row, TreeNode* node);//追加顶部节点TreeNode* appendTopItem(QString itemText);//删除顶部的item 以及数据列表void removeTopItem(TreeNode* node);//一个更新nodetext的变量保证每次更新节点都会变化int number 0;double m_NodeSize 0;double m_ScrollBarValue 0;bool m_BarValueChangedTemp false;bool m_WheelEventTemp false;//递归插入void RecursionInsert(TreeNode* ParentNode, TreeNode* childNode);//展开所有子节点void expandAllItems(QTreeWidget* treeWidget, QTreeWidgetItem* item);void onScrollBarValueChanged(int value);
protected:void mouseMoveEvent(QMouseEvent *event);void mousePressEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);void startDrag(Qt::DropActions supportedActions);void dragEnterEvent(QDragEnterEvent *event);void dragMoveEvent(QDragMoveEvent *event);void dropEvent(QDropEvent *event);void paintEvent(QPaintEvent* event);void wheelEvent(QWheelEvent *event);
private:TreeNode* m_CopyNode nullptr; //当前拷贝的节点QPoint m_DragMovePos; //拖拽移动坐标QPoint m_CurPos; //点击保存坐标int m_LastScrollBarValue 0;QMenu* m;MyTreeWidgetItem* m_CurrDragItem nullptr; //保存当前正在拖拽的对象QScrollBar *m_VerticalScrollBar;
};#endif // MYTREEWIDGET_H
/******************************************************************************** Copyright [2023] 键鼠自动化* All rights reserved.** version: 1.0* author: lx* brief: 自定义item,重写绘制和拖拽,以及建立数据结构
*******************************************************************************/
#include mytreewidget.hMyTreeWidget::MyTreeWidget(QWidget *parent): QTreeWidget(parent)
{setDragEnabled(true);setAcceptDrops(true);setDragDropMode(DragDropMode::InternalMove);setHeaderHidden(true);m_VerticalScrollBar this-verticalScrollBar();connect(m_VerticalScrollBar, QScrollBar::valueChanged, this, MyTreeWidget::onScrollBarValueChanged);m new QMenu(this);QAction* action1 new QAction(删除);QAction* action2 new QAction(复制);QAction* action3 new QAction(粘贴);connect(action1, QAction::triggered, []() {MyTreeWidgetItem* targetItem dynamic_castMyTreeWidgetItem*(itemAt(m_CurPos));if (targetItem) {TreeNode* targetNode findNodeByText(targetItem-getNodeText(), m_ListData);if (targetNode-parent nullptr) {this-removeTopItem(targetNode);}else {targetNode-parent-item-removeChild(targetNode-item);deleteChildNode(targetNode-parent, targetNode-nodeText);}}qDebug() 1231231;});connect(action2, QAction::triggered, [](){MyTreeWidgetItem* targetItem dynamic_castMyTreeWidgetItem*(itemAt(m_CurPos));if (targetItem) {m_CopyNode findNodeByText(targetItem-getNodeText(), m_ListData);}});connect(action3, QAction::triggered, []() {MyTreeWidgetItem* targetItem dynamic_castMyTreeWidgetItem*(itemAt(m_CurPos));if (targetItem m_CopyNode ! nullptr) {TreeNode* targetNode findNodeByText(targetItem-getNodeText(), m_ListData);if (targetNode-parent nullptr) {int targetRow this-indexOfTopLevelItem(targetNode-item);if (m_CopyNode-children.isEmpty()) {this-insertTopItem(targetRow 1, m_CopyNode-nodeItemTest);}else {TreeNode* newParentNode this-insertTopItem(targetRow 1, m_CopyNode-nodeItemTest);for (int i 0 ; i m_CopyNode-children.size(); i) {this-RecursionInsert(newParentNode, m_CopyNode-children.at(i));}}}else {int targetRow targetNode-parent-item-indexOfChild(targetNode-item);if (m_CopyNode-children.isEmpty()) {this-insertChileItem(targetNode-parent, targetRow 1, m_CopyNode-nodeItemTest);}else {TreeNode* newParentNode this-insertChileItem(targetNode-parent, targetRow 1, m_CopyNode-nodeItemTest);for (int i 0 ; i m_CopyNode-children.size(); i) {this-RecursionInsert(newParentNode, m_CopyNode-children.at(i));}}}m_CopyNode nullptr;}});m-addAction(action1);m-addAction(action2);m-addAction(action3);
}void MyTreeWidget::wait(int ms)
{QElapsedTimer t;t.start();while (t.elapsed() ms)QCoreApplication::processEvents();
}TreeNode *MyTreeWidget::insertChileItem(TreeNode *parentNode, int row, QString itemText)
{number;QTreeWidgetItem* parentItem parentNode-item; //获取父节点MyTreeWidgetItem* childItem new MyTreeWidgetItem(); //创建子节点childItem-setNodeText(QString(child%1).arg(number));MyLabel* label new MyLabel(itemText); //创建labelchildItem-m_Label label;TreeNode* childData new TreeNode; //创建子节点对象数据childData-parent parentNode;childData-item childItem;childData-nodeText QString(child%1).arg(number);childData-nodeItemTest itemText;parentNode-children.insert(row, childData); //父节点对象数据插入子节点parentItem-insertChild(row, childItem); //父节点item插入子节点itemsetItemWidget(childItem, 0, label); //item转换lablereturn childData;
}TreeNode *MyTreeWidget::appendChileItem(TreeNode *parentNode, QString itemText)
{number;QTreeWidgetItem* parentItem parentNode-item;MyTreeWidgetItem* childItem new MyTreeWidgetItem();childItem-setNodeText(QString(child%1).arg(number));MyLabel* label new MyLabel(itemText);childItem-m_Label label;TreeNode* childData new TreeNode;childData-parent parentNode;childData-item childItem;childData-nodeText QString(child%1).arg(number);childData-nodeItemTest itemText;parentNode-children.append(childData);parentItem-addChild(childItem);setItemWidget(childItem, 0, label);return childData;
}TreeNode* MyTreeWidget::insertTopItem(int row, QString itemText, bool isInster)
{number;MyTreeWidgetItem* parentItem new MyTreeWidgetItem();parentItem-setNodeText(QString(parent%1).arg(number));TreeNode* parentData new TreeNode;parentData-item parentItem;parentData-nodeText QString(parent%1).arg(number);parentData-nodeItemTest itemText;if (isInster) {MyLabel* label new MyLabel(itemText);parentItem-m_Label label;insertTopLevelItem(row, parentItem);setItemWidget(parentItem, 0, label);}m_ListData.insert(row, parentData);return parentData;
}void MyTreeWidget::updateItem(int row, TreeNode *node)
{qDebug() row node-nodeItemTest aaaa;MyLabel* label new MyLabel(node-nodeItemTest);node-item-m_Label label;insertTopLevelItem(row, node-item);
// setItemWidget(node-item, 0, label);
}TreeNode *MyTreeWidget::appendTopItem(QString itemText)
{number;MyTreeWidgetItem* parentItem new MyTreeWidgetItem();parentItem-setNodeText(QString(parent%1).arg(number));MyLabel* label new MyLabel(itemText);parentItem-m_Label label;TreeNode* parentData new TreeNode;parentData-item parentItem;parentData-nodeText QString(parent%1).arg(number);parentData-nodeItemTest itemText;addTopLevelItem(parentItem);setItemWidget(parentItem, 0, label);m_ListData.append(parentData);return parentData;
}void MyTreeWidget::removeTopItem(TreeNode *node)
{int index indexOfTopLevelItem(node-item);takeTopLevelItem(index);deleteNodeByText(node-nodeText);
}void MyTreeWidget::RecursionInsert(TreeNode *ParentNode, TreeNode *childNode)
{TreeNode* node this-appendChileItem(ParentNode, childNode-nodeItemTest);for (int i 0 ; i childNode-children.size(); i) {this-RecursionInsert(node, childNode-children.at(i));}
}void MyTreeWidget::expandAllItems(QTreeWidget *treeWidget, QTreeWidgetItem *item)
{if (item) {treeWidget-expandItem(item); // 展开当前项// 递归展开子项for (int i 0; i item-childCount(); i) {expandAllItems(treeWidget, item-child(i));}}
}void MyTreeWidget::onScrollBarValueChanged(int value)
{//m_BarValueChangedTemp用于该函数在没有结束的时候又进来了如果不调用takeTopLevelItem就没事如果没有m_BarValueChangedTemp在该函数未结束还会进入导致崩溃int step 3; //滚动一次刷新三条数据if (value m_VerticalScrollBar-maximum()) {for (int index 0; index 1; index) {int itemCount this-topLevelItemCount();MyTreeWidgetItem* bottomItem dynamic_castMyTreeWidgetItem*(this-topLevelItem(itemCount - 1));TreeNode* bottomNode findNodeByText(bottomItem-getNodeText(), m_ListData);int bottomIndex m_ListData.indexOf(bottomNode);if (bottomIndex 100 m_ListData.size()) {step 1000;}else {step (m_ListData.size() - 1) - bottomIndex;}for (int i 0 ; i step; i) {//尾部追加显示//获取当前底部的数据bottomIndex;updateItem(itemCount, m_ListData.at(bottomIndex));itemCount;}for (int i 0 ; i step; i) {takeTopLevelItem(0);}}qDebug() QDateTime::currentDateTime() 222222222222222222;m_VerticalScrollBar-setValue(value-5);}/* if (m_BarValueChangedTemp) {qDebug() onScrollBarValueChanged未结束就进入;return;}if (m_WheelEventTemp) {qDebug() wheelEvent正在滚动中;return;}m_BarValueChangedTemp true;qDebug() value m_LastScrollBarValue this-topLevelItemCount();int step 3; //滚动一次刷新三条数据if (m_LastScrollBarValue value) {// 上拉int number m_LastScrollBarValue - value;for (int index 0; index number; index) {MyTreeWidgetItem* topItem dynamic_castMyTreeWidgetItem*(this-topLevelItem(0));TreeNode* topNode findNodeByText(topItem-getNodeText(), m_ListData);int topIndex m_ListData.indexOf(topNode);if (topIndex - 3 0) {step 3;}else {step topIndex;}for (int i step; i 0; --i) {//尾部追加显示//获取当前底部的数据topIndex--;updateItem(0, m_ListData.at(topIndex));}for (int i 0 ; i step; i) {takeTopLevelItem(this-topLevelItemCount() - 1);}}}else {int number value - m_LastScrollBarValue;qDebug() QDateTime::currentDateTime() 111111111111111;for (int index 0; index number; index) {int itemCount this-topLevelItemCount();MyTreeWidgetItem* bottomItem dynamic_castMyTreeWidgetItem*(this-topLevelItem(itemCount - 1));TreeNode* bottomNode findNodeByText(bottomItem-getNodeText(), m_ListData);int bottomIndex m_ListData.indexOf(bottomNode);if (bottomIndex 3 m_ListData.size()) {step 3;}else {step (m_ListData.size() - 1) - bottomIndex;}for (int i 0 ; i step; i) {//尾部追加显示//获取当前底部的数据bottomIndex;updateItem(itemCount, m_ListData.at(bottomIndex));itemCount;}for (int i 0 ; i step; i) {takeTopLevelItem(0);}}qDebug() QDateTime::currentDateTime() 222222222222222222;}m_ScrollBarValue value;m_LastScrollBarValue value;m_VerticalScrollBar-setValue(value);m_BarValueChangedTemp false;*/
}void MyTreeWidget::mouseMoveEvent(QMouseEvent *event)
{QTreeWidget::mouseMoveEvent(event);
}void MyTreeWidget::mousePressEvent(QMouseEvent *event)
{QTreeWidget::mousePressEvent(event);m_CurPos event-pos();if (event-buttons() Qt::RightButton) {m-move((QCursor::pos()));m-show();}}void MyTreeWidget::mouseReleaseEvent(QMouseEvent *event)
{QTreeWidget::mouseReleaseEvent(event);
}void MyTreeWidget::startDrag(Qt::DropActions supportedActions)
{//拖拽重写此函数下发当前拖拽对象的nodetextQ_UNUSED(supportedActions);MyTreeWidgetItem* currItem dynamic_castMyTreeWidgetItem*(this-currentItem());if (currItem) {QString text currItem-getNodeText();QMimeData* mimeData new QMimeData;mimeData-setData(application/labelData, text.toUtf8());QDrag* drag new QDrag(this);drag-setMimeData(mimeData);m_CurrDragItem currItem;drag-start(Qt::MoveAction);}
}void MyTreeWidget::dragEnterEvent(QDragEnterEvent *event)
{QTreeWidget::dragEnterEvent(event);// 检查拖拽数据格式if (event-mimeData()-hasFormat(application/labelData)) {event-acceptProposedAction();}
}void MyTreeWidget::dragMoveEvent(QDragMoveEvent *event)
{QTreeWidget::dragMoveEvent(event);// 检查拖拽数据格式if (event-mimeData()-hasFormat(application/labelData)) {event-acceptProposedAction();m_DragMovePos event-pos();viewport()-update();}}void debugTreeData(TreeNode* node, int depth 0) {QString kongge;for (int i 0; i depth; i) {kongge.append(----);}qDebug() kongge node-nodeItemTest node-nodeText;for (int i 0; i node-children.size(); i) {debugTreeData(node-children.at(i), depth 1); // 递归时深度加1}
}void MyTreeWidget::dropEvent(QDropEvent *event)
{// 检查拖拽数据格式if (event-mimeData()-hasFormat(application/labelData)) {QString itemData event-mimeData()-data(application/labelData);MyTreeWidgetItem* targetItem dynamic_castMyTreeWidgetItem*(itemAt(event-pos()));m_CurrDragItem nullptr;if (!targetItem) {return;}qDebug() itemData ------------------- targetItem-getNodeText();TreeNode* targetNode findNodeByText(targetItem-getNodeText(), m_ListData);TreeNode* sourceNode findNodeByText(itemData, m_ListData);if (sourceNode targetNode) {// 找到了匹配的节点可以对其进行操作qDebug() 找到了匹配的节点可以对其进行操作 targetNode-nodeText sourceNode-nodeText;if (sourceNode-parent nullptr targetNode-parent nullptr) { //父与父//当前是父节点与父节点直接拖拽int targetRow this-indexOfTopLevelItem(targetNode-item);int sourceRow this-indexOfTopLevelItem(sourceNode-item);if (targetRow ! sourceRow) {qDebug() 1111111111111111 targetRow sourceRow;//在目标源下插入一行if (sourceNode-children.isEmpty()) {this-insertTopItem(targetRow 1, sourceNode-nodeItemTest);//删除来源itemthis-removeTopItem(sourceNode);}else if (!sourceNode-children.isEmpty()) {//如果来源里面有子节点就需要递归插入,先查入头节点TreeNode* newParentNode this-insertTopItem(targetRow 1, sourceNode-nodeItemTest);for (int i 0 ; i sourceNode-children.size(); i) {this-RecursionInsert(newParentNode, sourceNode-children.at(i));}//删除来源itemthis-removeTopItem(sourceNode);deleteNodeByText(sourceNode-nodeText);}else {qDebug() 未知动作!!!!!!!!!!!!!!!!!!!!!!!!;}}}else if (sourceNode-parent ! nullptr targetNode-parent ! nullptr) { //子与子//双方都是子节点int targetRow targetNode-parent-item-indexOfChild(targetNode-item);int sourceRow sourceNode-parent-item-indexOfChild(sourceNode-item);qDebug() 44444444444444 targetRow sourceRow sourceNode-nodeItemTest targetNode-nodeItemTest;if (recursiveFindNodeByText(targetNode-nodeText, sourceNode) ! nullptr) {//来源节点中不能有目标节点return;}if (sourceNode-children.isEmpty()) {this-insertChileItem(targetNode-parent, targetRow 1, sourceNode-nodeItemTest);sourceNode-parent-item-removeChild(sourceNode-item);deleteChildNode(sourceNode-parent, sourceNode-nodeText);}else if (!sourceNode-children.isEmpty()) {TreeNode* newParentNode this-insertChileItem(targetNode-parent, targetRow 1, sourceNode-nodeItemTest);for (int i 0 ; i sourceNode-children.size(); i) {this-RecursionInsert(newParentNode, sourceNode-children.at(i));}//删除来源itemsourceNode-parent-item-removeChild(sourceNode-item);deleteChildNode(sourceNode-parent, sourceNode-nodeText);}}else if (sourceNode-parent ! nullptr targetNode-parent nullptr) { //子与父//来源是子节点指向端是父节点int targetRow this-indexOfTopLevelItem(targetNode-item);int sourceRow sourceNode-parent-item-indexOfChild(sourceNode-item);qDebug() 222222222222222222 targetRow sourceRow sourceNode-parent-nodeItemTest sourceNode-nodeItemTest;if (sourceNode-children.isEmpty()) {this-insertTopItem(targetRow 1, sourceNode-nodeItemTest);sourceNode-parent-item-removeChild(sourceNode-item);deleteChildNode(sourceNode-parent, sourceNode-nodeText);}else if (!sourceNode-children.isEmpty()) {TreeNode* newParentNode this-insertTopItem(targetRow 1, sourceNode-nodeItemTest);for (int i 0 ; i sourceNode-children.size(); i) {this-RecursionInsert(newParentNode, sourceNode-children.at(i));}//删除来源itemsourceNode-parent-item-removeChild(sourceNode-item);deleteChildNode(sourceNode-parent, sourceNode-nodeText);}}else if (sourceNode-parent nullptr sourceNode-children.isEmpty() targetNode-parent ! nullptr) { //空父 与子//来源父节点 且没有子节点 且指向端是子节点int targetRow targetNode-parent-item-indexOfChild(targetNode-item);int sourceRow this-indexOfTopLevelItem(sourceNode-item);qDebug() 333333333333 targetRow sourceRow sourceNode-nodeItemTest targetNode-nodeItemTest;this-insertChileItem(targetNode-parent, targetRow 1, sourceNode-nodeItemTest);this-removeTopItem(sourceNode);}else if (sourceNode-parent nullptr !sourceNode-children.isEmpty() targetNode-parent ! nullptr) { //父多子 与子//来源父节点 有子节点 且指向端是子节点if (recursiveFindNodeByText(targetNode-nodeText, sourceNode) ! nullptr) {//来源节点中不能有目标节点return;}int targetRow targetNode-parent-item-indexOfChild(targetNode-item);int sourceRow this-indexOfTopLevelItem(sourceNode-item);qDebug() 5555555555555 targetRow sourceRow sourceNode-nodeItemTest targetNode-nodeItemTest;TreeNode* newParentNode this-insertChileItem(targetNode-parent, targetRow 1, sourceNode-nodeItemTest);for (int i 0 ; i sourceNode-children.size(); i) {this-RecursionInsert(newParentNode, sourceNode-children.at(i));}//删除来源itemthis-removeTopItem(sourceNode);deleteNodeByText(sourceNode-nodeText);}} else {// 未找到匹配的节点qDebug() 未找到匹配的节点2;}}// for (int i 0; i m_ListData.size(); i) {// debugTreeData(m_ListData.at(i));// }
}void MyTreeWidget::paintEvent(QPaintEvent *event)
{// qDebug() 123123123123;QTreeWidget::paintEvent(event);QPainter painter(viewport());if (m_CurrDragItem ! nullptr) {QModelIndex hoveredIndex indexAt(m_DragMovePos);MyTreeWidgetItem* mcurrMoveItem dynamic_castMyTreeWidgetItem*(itemFromIndex(hoveredIndex));if (mcurrMoveItem) {QRect rect visualRect(hoveredIndex); // 获取悬停项的矩形区域QString labelText mcurrMoveItem-m_Label-text();qDebug() --------------- labelText rect -----------------;painter.setPen(QPen(QColor(34, 142, 243), 2)); // 设置线条颜色和粗细// 绘制线条painter.drawLine(rect.x() 6, rect.y() rect.height(), rect.x() rect.width() - 6, rect.y() rect.height()); // 绘制底部线条// 绘制头部小圆圈painter.setBrush(QBrush(QColor(34, 142, 243))); // 设置圆圈颜色painter.drawEllipse(QPoint(rect.x() 2, rect.y() rect.height()), 2, 2); // 绘制小圆圈// 绘制尾部小圆圈painter.drawEllipse(QPoint(rect.x() rect.width()-2, rect.y() rect.height()), 2, 2); // 绘制小圆圈}}
}void MyTreeWidget::wheelEvent(QWheelEvent *event)
{if (m_WheelEventTemp) {qDebug() wheelEvent未结束就进入;return;}if (m_VerticalScrollBar-isSliderDown()) {qDebug() 正在拖拽滚动条;return;}m_WheelEventTemp true;qDebug() 1111111111111111111 event-angleDelta().y() this-topLevelItemCount() m_VerticalScrollBar-isSliderDown();int number qAbs(event-angleDelta().y()) / 120;int step 3; //滚动一次刷新三条数据for (int i 0; i number; i) {if (event-angleDelta().y() 0) {MyTreeWidgetItem* topItem dynamic_castMyTreeWidgetItem*(this-topLevelItem(0));TreeNode* topNode findNodeByText(topItem-getNodeText(), m_ListData);int topIndex m_ListData.indexOf(topNode);if (topIndex - 3 0) {step 3;}else {step topIndex;}for (int i step; i 0; --i) {//尾部追加显示//获取当前底部的数据topIndex--;updateItem(0, m_ListData.at(topIndex));}for (int i 0 ; i step; i) {takeTopLevelItem(this-topLevelItemCount() - 1);}if (m_ScrollBarValue 0) {m_ScrollBarValue - double(m_VerticalScrollBar-maximum()) / double(m_ListData.size() / (step 0 ? 1 : step));qDebug() 向上滚动 topIndex m_ScrollBarValue;m_VerticalScrollBar-setValue(m_ScrollBarValue);}}else {int itemCount this-topLevelItemCount();MyTreeWidgetItem* bottomItem dynamic_castMyTreeWidgetItem*(this-topLevelItem(itemCount - 1));TreeNode* bottomNode findNodeByText(bottomItem-getNodeText(), m_ListData);int bottomIndex m_ListData.indexOf(bottomNode);if (bottomIndex3 m_ListData.size()) {step 3;}else {step (m_ListData.size() - 1) - bottomIndex;}for (int i 0 ; i step; i) {//尾部追加显示//获取当前底部的数据bottomIndex;updateItem(itemCount, m_ListData.at(bottomIndex));itemCount;}for (int i 0 ; i step; i) {takeTopLevelItem(0);}if (m_VerticalScrollBar-value() m_VerticalScrollBar-maximum()) {m_ScrollBarValue double(m_VerticalScrollBar-maximum()) / double(m_ListData.size() / (step 0 ? 1 : step));qDebug() 向下滚动 bottomIndex m_ScrollBarValue;m_VerticalScrollBar-setValue(m_ScrollBarValue);}}}m_WheelEventTemp false;
}MyTreeWidgetItem::MyTreeWidgetItem()
{}void MyTreeWidgetItem::setNodeText(QString str)
{m_Text str;
}QString MyTreeWidgetItem::getNodeText()
{return m_Text;
}MyLabel::MyLabel(QString text, QWidget *parent): QLabel(parent)
{setText(text);installEventFilter(this);enterStyle background-color: rgb(225, 243, 255);;leaveStyle background-color: white;;selectStyle background-color: rgb(204, 232, 255);;
}bool MyLabel::eventFilter(QObject *watched, QEvent *event)
{return QWidget::eventFilter(watched, event);
}
#include widget.h
#include ui_widget.hWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);m_MyTreeWidget new MyTreeWidget();// if (1) {qDebug() QDateTime::currentDateTime() 111111111111111;for (int i 0; i 100000; i) {if (i 100) {m_MyTreeWidget-insertTopItem(i, QString(父节点%1).arg(i1), false);}else {m_MyTreeWidget-insertTopItem(i, QString(父节点%1).arg(i1));}}qDebug() QDateTime::currentDateTime() 2222222222222;// for (int i 0; i 500; i) {// m_MyTreeWidget-insertChileItem(m_MyTreeWidget-m_ListData.at(0), m_MyTreeWidget-m_ListData.at(0)-item-childCount(),QString(子节点%1).arg(i1));// }// for (int i 0; i 500; i) {// m_MyTreeWidget-insertChileItem(m_MyTreeWidget-m_ListData.at(1), m_MyTreeWidget-m_ListData.at(1)-item-childCount(),QString(子节点%1).arg(i1));// }// for (int i 0; i 500; i) {// m_MyTreeWidget-insertChileItem(m_MyTreeWidget-m_ListData.at(2), m_MyTreeWidget-m_ListData.at(2)-item-childCount(),QString(子节点%1).arg(i1));// }// for (int i 0; i 500; i) {// m_MyTreeWidget-insertChileItem(m_MyTreeWidget-m_ListData.at(3), m_MyTreeWidget-m_ListData.at(3)-item-childCount(),QString(子节点%1).arg(i1));// }ui-gridLayout-addWidget(m_MyTreeWidget);// 在您的代码中调用此函数来展开所有项//m_MyTreeWidget-expandAllItems(m_MyTreeWidget, m_MyTreeWidget-invisibleRootItem());
}Widget::~Widget()
{delete ui;
} 文章转载自: http://www.morning.pslzp.cn.gov.cn.pslzp.cn http://www.morning.psyrz.cn.gov.cn.psyrz.cn http://www.morning.jltmb.cn.gov.cn.jltmb.cn http://www.morning.nsmyj.cn.gov.cn.nsmyj.cn http://www.morning.qjbxt.cn.gov.cn.qjbxt.cn http://www.morning.txtzr.cn.gov.cn.txtzr.cn http://www.morning.trtdg.cn.gov.cn.trtdg.cn http://www.morning.pmrlt.cn.gov.cn.pmrlt.cn http://www.morning.kxqfz.cn.gov.cn.kxqfz.cn http://www.morning.pslzp.cn.gov.cn.pslzp.cn http://www.morning.nndbz.cn.gov.cn.nndbz.cn http://www.morning.wmlby.cn.gov.cn.wmlby.cn http://www.morning.bdfph.cn.gov.cn.bdfph.cn http://www.morning.dschz.cn.gov.cn.dschz.cn http://www.morning.bswnf.cn.gov.cn.bswnf.cn http://www.morning.fwblh.cn.gov.cn.fwblh.cn http://www.morning.pmdnx.cn.gov.cn.pmdnx.cn http://www.morning.fnkcg.cn.gov.cn.fnkcg.cn http://www.morning.jxhlx.cn.gov.cn.jxhlx.cn http://www.morning.yunease.com.gov.cn.yunease.com http://www.morning.qbwmz.cn.gov.cn.qbwmz.cn http://www.morning.sgtq.cn.gov.cn.sgtq.cn http://www.morning.mxhgy.cn.gov.cn.mxhgy.cn http://www.morning.hhqjf.cn.gov.cn.hhqjf.cn http://www.morning.dthyq.cn.gov.cn.dthyq.cn http://www.morning.rbjth.cn.gov.cn.rbjth.cn http://www.morning.mkyxp.cn.gov.cn.mkyxp.cn http://www.morning.ybshj.cn.gov.cn.ybshj.cn http://www.morning.ypzsk.cn.gov.cn.ypzsk.cn http://www.morning.cjmmt.cn.gov.cn.cjmmt.cn http://www.morning.rbgqn.cn.gov.cn.rbgqn.cn http://www.morning.wjtwn.cn.gov.cn.wjtwn.cn http://www.morning.fmrd.cn.gov.cn.fmrd.cn http://www.morning.fqtzn.cn.gov.cn.fqtzn.cn http://www.morning.zhffz.cn.gov.cn.zhffz.cn http://www.morning.gbcnz.cn.gov.cn.gbcnz.cn http://www.morning.hjlwt.cn.gov.cn.hjlwt.cn http://www.morning.zpdjh.cn.gov.cn.zpdjh.cn http://www.morning.gglhj.cn.gov.cn.gglhj.cn http://www.morning.drnjn.cn.gov.cn.drnjn.cn http://www.morning.mnsmb.cn.gov.cn.mnsmb.cn http://www.morning.bcjbm.cn.gov.cn.bcjbm.cn http://www.morning.nbqwr.cn.gov.cn.nbqwr.cn http://www.morning.jnzfs.cn.gov.cn.jnzfs.cn http://www.morning.crfyr.cn.gov.cn.crfyr.cn http://www.morning.qhydkj.com.gov.cn.qhydkj.com http://www.morning.hous-e.com.gov.cn.hous-e.com http://www.morning.qhjkz.cn.gov.cn.qhjkz.cn http://www.morning.csnmd.cn.gov.cn.csnmd.cn http://www.morning.nbsfb.cn.gov.cn.nbsfb.cn http://www.morning.fblkr.cn.gov.cn.fblkr.cn http://www.morning.kbdrq.cn.gov.cn.kbdrq.cn http://www.morning.nrzkg.cn.gov.cn.nrzkg.cn http://www.morning.fqtdz.cn.gov.cn.fqtdz.cn http://www.morning.xphls.cn.gov.cn.xphls.cn http://www.morning.srltq.cn.gov.cn.srltq.cn http://www.morning.hslgq.cn.gov.cn.hslgq.cn http://www.morning.cbtn.cn.gov.cn.cbtn.cn http://www.morning.deanzhu.com.gov.cn.deanzhu.com http://www.morning.lfgql.cn.gov.cn.lfgql.cn http://www.morning.rgwz.cn.gov.cn.rgwz.cn http://www.morning.ynlpy.cn.gov.cn.ynlpy.cn http://www.morning.ctwwq.cn.gov.cn.ctwwq.cn http://www.morning.pwwjs.cn.gov.cn.pwwjs.cn http://www.morning.youprogrammer.cn.gov.cn.youprogrammer.cn http://www.morning.ppllj.cn.gov.cn.ppllj.cn http://www.morning.lwzgn.cn.gov.cn.lwzgn.cn http://www.morning.kcxtz.cn.gov.cn.kcxtz.cn http://www.morning.rcttz.cn.gov.cn.rcttz.cn http://www.morning.myrmm.cn.gov.cn.myrmm.cn http://www.morning.kaakyy.com.gov.cn.kaakyy.com http://www.morning.gcfg.cn.gov.cn.gcfg.cn http://www.morning.kjjbz.cn.gov.cn.kjjbz.cn http://www.morning.npbnc.cn.gov.cn.npbnc.cn http://www.morning.qgqck.cn.gov.cn.qgqck.cn http://www.morning.bklkt.cn.gov.cn.bklkt.cn http://www.morning.wfjyn.cn.gov.cn.wfjyn.cn http://www.morning.lqytk.cn.gov.cn.lqytk.cn http://www.morning.rblqk.cn.gov.cn.rblqk.cn http://www.morning.fyxtn.cn.gov.cn.fyxtn.cn