目录
一、概述
QT中提供的标准控件能够满足我们大多数情况下的功能需求,但是在一些特殊应用场合,我们可能需要对控件的功能进行扩展,或者改写控件的功能实现。为满足此需求,QT提供了对标准控件的提升功能,用于重新自定义标准控件的实现。本文以QListWidget控件为例,详细介绍了控件提升的具体操作和实现。
二、功能需求
我们需要实现在QListWidget控件中选中项,然后再对选中项进行拖动操作。如果使用QListWidget控件的默认功能,发现在拖动选中项时,鼠标按下后,鼠标所在位置本已被选中的项将被取消选中,导致该项不能被同时拖动。分析原因是,QListWidget控件在标记选中项的操作是在鼠标左键按下时执行的,即当鼠标左键按下事件发生时,QListWidget控件中项目的选中状态就会立即切换。因此,要实现对所有选中项的拖动,需要改写QListWidget控件的鼠标单击事件函数。而我们不可能去改写QT提供的标准控件的实现代码,所以,此处可以采用控件提升的方式,用我们自定义的类来提升标准控件,从而实现改写标准控件功能的目的。
三、提升操作
1)拖入标准控件
首先我们可以新建一个QWidget项目,在QWidget控件中拖入QListWidget控件,如下图所示。
2)自定义类
在项目工程目录中添加一个C++类,包.h文件和.cpp文件。类的名称可以自己定义。头文件的代码实现如下。该类继承自QListWidget,注意此处继承的类必须与被提升的类相同。类中定义了一个私有成员变量,用于记录点击的项item。然后申明了构造函数和需要重写的两个虚函数,鼠标按下事件和鼠标移动事件。
#ifndef SLISTWIDGET_H
#define SLISTWIDGET_H
#include <QObject>
#include <QWidget>
#include <QListWidget>
#include <QMouseEvent>
#include <QDragMoveEvent>
class SListWidget: public QListWidget
{
Q_OBJECT
private:
QListWidgetItem *clickeditem;//记录下点击的Item
public:
explicit SListWidget(QWidget *parent = nullptr);
virtual void mousePressEvent(QMouseEvent *e)override;
virtual void mouseMoveEvent(QMouseEvent *e)override;
};
#endif // SLISTWIDGET_H
函数的代码实现如下。在mousePressEvent函数实现中,当鼠标按下时,首先执行QListWidget控件的默认鼠标按下事件函数,然后将此时点击的项记录下来,获取它的指针。如果指针为空,则清除所有已选择的项。该功能可以实现在单击控件的空白处时,取消所有选择的功能。
在mouseMoveEvent函数实现中,当鼠标移动时,首先判断当前鼠标按下的是左键,然后判断记录的项不为空,再后就是切换记录项的选择状态。此处逻辑可以实现在按下左键的同时移动鼠标时,之前选中的项保持选中,之前未被选中的项依然不被选中。如此设计是因为在按下左键拖动鼠标时,按下左键会改变项的选中状态。随后将记录的项置空,确保上述判断逻辑只执行一次,因为在鼠标移动过程中,mouseMoveEvent函数会被持续重复调用。最后任然执行QListWidget控件的默认mouseMoveEvent函数,确保拖动功能的正常执行。
#include "slistwidget.h"
SListWidget::SListWidget(QWidget *parent) : QListWidget(parent)
{
}
void SListWidget::mousePressEvent(QMouseEvent *e)
{
QListWidget::mousePressEvent(e);
// 获取当前鼠标位置对应的项
clickeditem = itemAt(e->pos());//记录下被选择的项
if (clickeditem) {
}
else
clearSelection();
}
void SListWidget::mouseMoveEvent(QMouseEvent *e)
{
if (e->buttons() & Qt::LeftButton) {
if(clickeditem){
if(!clickeditem->isSelected())
clickeditem->setSelected(true);
else
clickeditem->setSelected(false);
clickeditem = nullptr;
}
}
QListWidget::mouseMoveEvent(e);
}
3)提升控件
回到QT Creator的窗体设计界面,选中需要提升的QListWodget控件,单击鼠标右键选择“提升为...”选项,弹出如下窗口。按图中所示步骤,依次输入自定义的类名,点击添加按钮,然后选中添加的类,最后点击提升。如此便完成了对QListWidget控件的提升操作。