void SetRootNode(TreeNode *node); bool AddTreeNode(TreeNode* pNode); //添加一个子节点 int TreeNodeHaveEqualInfo(TreeNode* parentNode, TreeNode* pAddChildNode); //判断待加入节点,在父节点中是否有相同信息 TreeNode* FindParentNode(TreeNode* pNode, TreeNode* childNode); //根据给定的字节点,再根节点中,寻找其父节点 //结点所在的位置,和其父结点 TreeNode* NodeFromIndex(const QModelIndex &index) const; //实现 QAbstractItemModel的类的成员函数 QModelIndex index(int row, int column, const QModelIndex &parent) const; QModelIndex parent(const QModelIndex &child) const; int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const Qt::ItemFlags flag = QAbstractItemModel::flags(index); return flag | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; //允许Model拖动,这个很重要 QMimeData* mimeData(const QModelIndexList &indexes) const QMimeData* mimeD = QAbstractItemModel::mimeData(indexes); //先获取原始的mimeData; if (indexes.size() > 0) QModelIndex index = indexes.at(0); TreeModel* node = (TreeModel*)index.internalPointer(); QByteArray encoded; QDataStream stream(&encoded, QIODevice::WriteOnly); stream << (qint64)(node); mimeD->setData("Node/NodePtr", encoded); //将自己需要的数据 存入到MimeData中 mimeD->setData("Node/NodePtr", "NULL"); return mimeD; //mimeD->setData() public: TreeNode* mRootNode; //树的根结点

树形Model的实现

TreeModel::TreeModel(QObject* parent) : QAbstractItemModel(parent)
this->mRootNode = NULL;
//构造一个根节点,在Qt中根节点的父节点为空,默认不显示,构造一个空节点充当父节点
mRootNode = new TreeNode();
mRootNode->mParentNode = NULL;
TreeModel::~TreeModel()
	//将设备的根结点才此位置析构
	if (mRootNode)
		delete mRootNode;
	mRootNode = NULL;
//设置设备树的根结点
void TreeModel::SetRootNode(TreeNode *node)
	//要更新model数据时,先调用beginResetModel,结束时调用endResetModel,所有绑定在Model上的视图都会更新
	this->beginResetModel();
	if (mRootNode)
		delete mRootNode;
		mRootNode = NULL;
	mRootNode = node;
	endResetModel();
//往某个父节点,添加一个子节点,如果parentNode为空,添加到父节点下
bool TreeModel::AddTreeNode(TreeNode* pNode)
	if (this->TreeNodeHaveEqualInfo(mRootNode, pNode) > 0)			//如果待加入节点,在根节点中有相同Ip,不允许加入
		//TODO MSG
		delete pNode;												//不加入的节点 析构掉。
		return true;
	this->beginResetModel();
		if (!pNode->mParentNode)						//parentNode为空,直接加载在根节点下
			mRootNode->mChildNodes.append(pNode);
			pNode->mParentNode = mRootNode;
			break;
	} while (0);
	//如果parentNode在现有的树体系中,加入现有树体系,如果不在,加入根节点中
	/*TreeNode* pNode = FindParentNode(mRootNode, pNode->mParentNode);
	if (!pNode)
		mRootNode->mChildNodes.append(pNode);
		pNode->mParentNode = mRootNode;
		return true;
	this->endResetModel();
	return true;
//pNode 为要查找节点, childNode 为被查找节点,返回被查找节点的父节点,pNode和childNode之间有层级关系
TreeNode* TreeModel::FindParentNode(TreeNode* pNode, TreeNode* childNode)
	//if (!pNode)
	//	return NULL;
	//if (pNode->mChildNodes.indexOf(childNode))								//如果子节点在所在的父节点,返回父节点
	//	return pNode;
	//for (int i = 0; i < pNode->mChildNodes.count(); i++)
	//	return FindParentNode(pNode->mChildNodes.at(i), childNode);
	return NULL;
int TreeModel::TreeNodeHaveEqualInfo(TreeNode* parentNode, TreeNode* pAddChildNode)
	/*for (int i = 0; i < parentNode->mChildNodes.size(); i++)
		if (parentNode->mChildNodes.at(i)->mDeviceInfo.mDevIp != pAddChildNode->mDeviceInfo.mDevIp)
			continue;
			return 1;
	return 0;
//根据QModelIndex,返回指向其父结点的指针
TreeNode* TreeModel::NodeFromIndex(const QModelIndex &index) const
	if (index.isValid())				//如果是有效结点
		return static_cast<TreeNode*>(index.internalPointer());
		return mRootNode;
//重载实现的QAbstractItemModel类的函数,基类中带const的函数,重载时也要是const
//index函数,根据行,列,返回一个父结点为parent的元素
QModelIndex TreeModel::index(int row, int column,
	const QModelIndex &parent) const
	//如果参数条件不满足,返回为空
	if (!mRootNode || row < 0 || column < 0)
		return QModelIndex();
	TreeNode* parentNode = NodeFromIndex(parent);		//获取指向此结点的指针
	if (!parentNode)					//如果没有父结点
		return QModelIndex();
	TreeNode* rowNode = parentNode->mChildNodes.at(row);
	if (!rowNode)
		return QModelIndex();
	return this->createIndex(row, column, rowNode);			//创建一个QModelIndex,参数3为结点指向数据指针
QModelIndex TreeModel::parent(const QModelIndex &child) const
	TreeNode *node = NodeFromIndex(child);
	if (!node)
		return QModelIndex();
	TreeNode *parentNode = node->mParentNode;
	if (!parentNode)
		return QModelIndex();
	TreeNode *grandparentNode = parentNode->mParentNode;
	if (!grandparentNode)
		return QModelIndex();
	int row = grandparentNode->mChildNodes.indexOf(parentNode);
	return createIndex(row, 0, parentNode);
//返回给定父结点下,行的个数
int TreeModel::rowCount(const QModelIndex &parent) const
	if (parent.column() > 0)
		return 0;
	TreeNode* parentNode = NodeFromIndex(parent);
	if (!parentNode)
		return 0;
	return parentNode->mChildNodes.count();				//返回父结点中子结点个数   
int TreeModel::columnCount(const QModelIndex &parent) const
	return 1;											//返回列数,此处为1列
QVariant TreeModel::data(const QModelIndex &index, int role) const
	qDebug() << "TreeModel::data";
	switch (role)
	case Qt::DisplayRole:										//显示汉字
		TreeNode *node = NodeFromIndex(index);
		if (!node)
			return QVariant();
		if (index.column() == 0)
			return node->mText;				//显示设备的Ip
	break;
	case Qt::DecorationRole:									//图标相关的role
		//qDebug() << "Qt::DecorationRole";
		QPixmap Icon = QPixmap("D:/QtProject/QtGuiApplication1/release/33.png");		//在树上画图标
		QVariant var;
		var.setValue(Icon);
		return var;
	break;
	/*case Qt::UserRole:
		TreeNode *node = NodeFromIndex(index);
		QVariant var;
		var.setValue<TreeNode*>(node);
		return var;
	break;*/
	default:
		break;
	return QVariant();
QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const
	if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
		if (section == 0)
			return tr("Txt");
	return QVariant();

拖放界面的头文件

class TreeDrag : public QMainWindow
	Q_OBJECT
public:
	TreeDrag(QWidget *parent = Q_NULLPTR);
protected:
	void dropEvent(QDropEvent *event);								//放下动作
	void dragEnterEvent(QDragEnterEvent *event);					//托到进入窗口动作
	void dragMoveEvent(QDragMoveEvent *event);						//拖着物体在窗口移动
	void dragLeaveEvent(QDragLeaveEvent *event);					//拖走了没有释放
private:
	Ui::TreeDragClass ui;
	TreeModel* mModel;

拖放界面的实现

TreeDrag::TreeDrag(QWidget *parent)
	: QMainWindow(parent)
	ui.setupUi(this);
	this->setAcceptDrops(true);				//允许接受拖拽事件
	mModel = new TreeModel(this);
	TreeNode* node = new TreeNode();
	node->mText = "Test";
	node->mParentNode = NULL;
	for (int i = 0; i < 10; i++)
		TreeNode* childNode = new TreeNode();
		childNode->mText = QString("192.168.1.%1").arg(QString::number(100 + i + 1));
		childNode->mParentNode = node;
		node->mChildNodes.append(childNode);
	mModel->AddTreeNode(node);
	ui.treeView->setModel(mModel);
void TreeDrag::dragEnterEvent(QDragEnterEvent *event)
	QStringList formats = event->mimeData()->formats();
	qDebug() << "dragEnterEvent formats = " << formats;
	if (event->mimeData()->hasFormat("Node/NodePtr"))
		event->accept();
		event->ignore();
void TreeDrag::dragLeaveEvent(QDragLeaveEvent *event)
	qDebug() << "dragLeaveEvent";
void TreeDrag::dragMoveEvent(QDragMoveEvent *event)
	QStringList formats = event->mimeData()->formats();
	qDebug() << "dragMoveEvent formats = " << formats;
	if (event->mimeData()->hasFormat("Node/NodePtr")) {
		event->setDropAction(Qt::MoveAction);
		event->accept();
	else {
		event->ignore();
void TreeDrag::dropEvent(QDropEvent *event)
	QStringList formats = event->mimeData()->formats();
	qDebug() << "dropEvent formats = " << formats;
	if (event->mimeData()->hasFormat("Node/NodePtr"))
		QVariant varData = event->mimeData()->data("Node/NodePtr");
		QByteArray byteData = varData.toByteArray();
		QDataStream stream(&byteData, QIODevice::ReadWrite);
		qint64 node;
		stream >> (node);
		TreeNode* devNode = (TreeNode*)(node);
		if (devNode)
			ui.lineEdit->setText(devNode->mText);
		event->setDropAction(Qt::MoveAction);
		event->accept();
		event->ignore();

源代码连接

源代码连接:https://download.csdn.net/download/u013125105/11653837

QTreeView的拖拽功能Qt树形结构的拖拽功能(drag/drop)在这里插入图片描述效果图树形Model的定义树形Model的实现界面设置拖放界面的头文件拖放界面的实现源代码连接Qt树形结构的拖拽功能(drag/drop)效果图树形Model的定义class TreeNode{public:TreeNode(const QString&amp; text = “”) :mTex... 将如果想让控件仅仅支持拖拉的方式,那么将dragEnable进行打钩,并将dragDropMode设置DragOnly 当然如果想让控件支持两种模式,那么直接设置为DragDrop属性 如果想在QTreeView中将数据拖拉到QTableView中,那...
Qt实现Tree-->Table和Chart拖拽环境说明实现Tree-->Table和Chart拖拽的原因实现的功能可参考的例子界面展示 Qt版本:5.12 Mingw32 操作系统:win10 实现Tree–>Table和Chart拖拽的原因 为了提升显示的效果。 实现的功能 将窗口中左边的信息拖到右边 可参考的例子 Qt实现Table–>Table拖拽功能 因为别人托我做的一个小软件,还答应给一些报酬的,所以这部分的程序目前不能提供出来,只能展示一下最后的效果。 #include <qdrag.h> QtMyTreeWidget::QtMyTreeWidget(QWidget *parent) : QTreeWidget(parent) m_CtrlPresse.
qmake: QT += core 继承自: QObject 子类: QAbstractListModel, QAbstractProxyModel, and QAbstractTableModel QAbstractItemModel 类定义了item model必须使用的标准接口,以便能够与model/view体系结构中的其他组件进行交互。它不应该被
代码里面有tree view的节点操作,包括添加,当前点击检查,遍历等。具体介绍见: Qt树形控件QTreeView使用1——节点的添加删除操作: http://blog.csdn.net/czyt1988/article/details/18996407 Qt树形控件QTreeView使用2——复选框的设置: http://blog.csdn.net/czyt1988/article/details/19171727 利用C++11的function和bind功能,实现QStandardItemModel的通用遍历函数: http://blog.csdn.net/czyt1988/article/details/21093451
你可以使用QAction类来为QTreeView添加右键功能,例如:QTreeView *treeView = new QTreeView(); QAction *action = new QAction("Action", treeView); treeView->setContextMenuPolicy(Qt::ActionsContextMenu); treeView->addAction(action);
CSDN-Ada助手: Hi,博主大大,感谢您分享关于Qt3D模块的使用!非常有用呢!如果您还有更多Qt相关的经验和技巧,欢迎继续分享哦~ 我发现目前CSDN上缺少一些针对Qt的图形界面开发的文章,比如Qt中控件的自定义和样式表的运用等方面,这些都是非常实用的技能,我非常期待您能分享一篇有关Qt图形界面开发的技术博文。期待您的佳作! 为了方便博主创作,提高生产力,CSDN上线了AI写作助手功能,就在创作编辑器右侧哦~(https://mp.csdn.net/edit?utm_source=blog_comment_recall )诚邀您来加入测评,到此(https://activity.csdn.net/creatActivity?id=10450&utm_source=blog_comment_recall)发布测评文章即可获得「话题勋章」,同时还有机会拿定制奖牌。 Qt自定义控件----PushButton显示svg矢量图 宇宙的尽头是编制: 博主,请教下怎么去调用paintSvgBtn方法,感觉这个博客没有头,只有身材和尾巴。 QTreeView的拖拽功能 你好,请问显示盘符这个问题解决了么?? Qt5.11的QWebEngine编译 lmf19950324: E:\Qt\Qt5.11.1\5.11.1\Src\qtwebengine\include拷贝多了个Src吧,是要吧src中的头文件替换到bin\include下 Qt5.11的QWebEngine编译 应该可以吧,记不住了 几年前弄的了