Qt implementa un encabezado de encabezado personalizado

descripción

En muchos casos, es necesario personalizar el estilo del encabezado. En Qt. Si elimina el encabezado del título que viene con system. Entonces muchos atributos desaparecerán. Por ejemplo, el formulario no se puede arrastrar y soltar. No es posible estirar la ventana con el mouse.

Realice aproximadamente la idea

Agrega un diseño horizontal. Hay dos QLabel y tres QPushButton adentro. Se utilizan dos QLabel para mostrar el icono y el título de la ventana. Los tres QPushButtons corresponden a hidden. Maximizar y cerrar botones.
Luego, cuando el mouse está cerca del borde del formulario, es necesario cambiar la forma del cursor del mouse. Y puedes estirar la forma. Al mismo tiempo, puede arrastrar y soltar presionando el mouse sobre el título. Este encabezado de título mantiene QWidget * _ownerWidget internamente . De hecho, es la ventana propietaria de este encabezado de título. Luego, use filtros eventFilterde eventos para monitorear eventos como los eventos del mouse.
Código de implementación

void FCustomTitleWidget::setUpConnection()
{
    
    
	connect(_buttonHide, &QPushButton::clicked, this, &FCustomTitleWidget::onTargetWidgetHide);//隐藏按钮
	connect(_buttonMinOrMax, &QPushButton::clicked, this, &FCustomTitleWidget::onTargetWidgetMinOrMax);//最大化最小化按钮
	connect(_buttonClose, &QPushButton::clicked, this, &FCustomTitleWidget::onTargetWidgetClose);//关闭按钮
}

void FCustomTitleWidget::initUi()
{
    
    
	_layoutMain = new QHBoxLayout;
	_layoutMain->setContentsMargins(0, 0, 0, 0);
	_layoutMain->setSpacing(5);
	_labelIcon = new QLabel(this);
	_labelIcon->setObjectName("labelIcon");
	_labelTitle = new QLabel(this);
	_labelTitle->setObjectName("labelTitle");
	_buttonHide = new QPushButton(this);
	_buttonHide->setObjectName("buttonHide");
	_buttonMinOrMax = new QPushButton(this);
	_buttonMinOrMax->setObjectName("buttonMinOrMax");
	_buttonClose = new QPushButton(this);
	_buttonClose->setObjectName("buttonClose");
	_layoutMain->addWidget(_labelIcon);
	_layoutMain->addWidget(_labelTitle);
	_layoutMain->addStretch();
	_layoutMain->addWidget(_buttonHide);
	_layoutMain->addWidget(_buttonMinOrMax);
	_layoutMain->addWidget(_buttonClose);
	this->setLayout(_layoutMain);
}
void FCustomTitleWidget::setOwnerWidget(QWidget * target)//设置拥有窗体
{
    
    
	assert(target);
	if (_ownerWidget != target)
	{
    
    
		if (_ownerWidget)
		{
    
    
			_ownerWidget->removeEventFilter(this);
		}
		_ownerWidget = target;
		_ownerWidget->setAttribute(Qt::WA_Hover);//hover属性
		_ownerWidget->installEventFilter(this);//安装事件过滤器
		
	}
}

Implementación de arrastrar y soltar

Cuando se presiona el mouse. Registre la posición donde se presiona el mouse. Luego registre la diferencia con la última posición cuando se arrastra y mueve el mouse. Luego cambie la posición del formulario.
Código de implementación

		case QEvent::MouseButtonPress:
		{
    
    
			if (mouseEvent)
			{
    
    
				_mousePressedPoint = mouseEvent->pos();//记录下开始的位置
				_dragDir = getDragDirByMousePos(_mousePressedPoint);
				_lastMousePoint = mouseEvent->globalPos();
			}
		}
			break;
		case QEvent::MouseMove:
		{
    
    
			if (mouseEvent)
			{
    
    
				updateWidgetSizeByDragDir(_dragDir, mouseEvent->globalPos());//更改窗体大小或者位置
				_lastMousePoint = mouseEvent->globalPos();
			}
		}
			break;

Cambiar el cursor del mouse

Establecer las propiedades de_ownerWidget->setAttribute(Qt::WA_Hover); ** _ ownerWidget puede detectar eventos de desplazamiento del mouse. Luego, determine dónde está el mouse en _ownerWidget **. Si está alrededor, cambie la forma del cursor del mouse de acuerdo con la dirección.
Código de implementación

Qt::CursorShape FCustomTitleWidget::getCursorShapeByDragDir(DragDir dir)
{
    
    
	Qt::CursorShape shape = Qt::ArrowCursor;
	switch (dir)
	{
    
    
	case 	DragDirMove:
	{
    
    
		shape = Qt::ArrowCursor;
	}
	break;
	case	DragDirLeftUp:
	case	DragDirRightBottom:
	{
    
    
		shape = Qt::SizeFDiagCursor;
	}
	 break;
	case	DragDirUp:
	case	DragDirBottom:
	{
    
    
		shape = Qt::SizeVerCursor;
	}
	break;
	case	DragDirRightUp:
	case	DragDirLeftBottom:
	{
    
    
		shape = Qt::SizeBDiagCursor;
	}
	break;
	case	DragDirLeft:
	case	DragDirRight:
	{
    
    
		shape = Qt::SizeHorCursor;
	}
	 break;
	default:
		break;
	}
	return shape;
}

Forma de estiramiento del mouse

Primero, determine cómo cambiar la posición o el tamaño del formulario de acuerdo con la dirección del arrastre del mouse. Si el mouse no está alrededor, sino en el encabezado de este título. Luego es mover la posición del formulario. Si está por todas partes. Necesita cambiar la posición y el tamaño del formulario. Porque el autor no tiene herramientas de producción de GIF. Las representaciones no se publicarán. El efecto específico se puede ver en Visual Studio. Coloque el mouse alrededor del estudio visual. Puede encontrar que el cursor ha cambiado. Si hace clic en el encabezado de arriba, arrastre y suelte para cambiar la posición. Si se arrastra. Puede estirar para cambiar la posición del formulario.
Código de implementación

void FCustomTitleWidget::updateWidgetSizeByDragDir(DragDir dragDir, const QPoint &mousePos)
{
    
    
	if (_ownerWidget == nullptr)
	{
    
    
		return;
	}
	auto widgetGeometry = _ownerWidget->geometry();
	switch (dragDir)
	{
    
    
	case 	DragDirMove:
	{
    
    
		_ownerWidget->move(mousePos.x() - _lastMousePoint.x()+_ownerWidget->pos().x(), mousePos.y() - _lastMousePoint.y() + _ownerWidget->pos().y());
	}
	break;
	case	DragDirLeftUp:
	{
    
    
		widgetGeometry.setTopLeft(mousePos);
		_ownerWidget->setGeometry(widgetGeometry);
	}
	break;
	case	DragDirRightBottom:
	{
    
    
		widgetGeometry.setBottomRight(mousePos);
		_ownerWidget->setGeometry(widgetGeometry);
	}
	break;
	case	DragDirUp:
	{
    
    
		widgetGeometry.setTop(mousePos.y());
		_ownerWidget->setGeometry(widgetGeometry);
	}
	break;
	case	DragDirBottom:
	{
    
    
		widgetGeometry.setBottom(mousePos.y());
		_ownerWidget->setGeometry(widgetGeometry);
	}
	break;
	case	DragDirRightUp:
	{
    
    
		widgetGeometry.setTopRight(mousePos);
		_ownerWidget->setGeometry(widgetGeometry);
	}
	break;
	case	DragDirLeftBottom:
	{
    
    
		widgetGeometry.setBottomLeft(mousePos);
		_ownerWidget->setGeometry(widgetGeometry);
	}
	break;
	case	DragDirLeft:
	{
    
    
		widgetGeometry.setLeft(mousePos.x());
		_ownerWidget->setGeometry(widgetGeometry);
	}
	break;
	case	DragDirRight:
	{
    
    
		widgetGeometry.setRight(mousePos.x());
		_ownerWidget->setGeometry(widgetGeometry);
	}
	break;
	default:
		break;
	}
}

Ejemplo de uso

#include "FCustomTitleWidget.h"//自定义标题头
#include <QVBoxLayout>
#include <QTableWidget>
class TestTitleWidget : public QWidget
{
    
    
public:
	TestTitleWidget()
	{
    
    
		_layout = new QVBoxLayout;
		this->setLayout(_layout);
		_titleWidget = new FCustomTitleWidget;
		_titleWidget->setOwnerWidget(this);//设置标题头的拥有窗体
		_layout->addWidget(_titleWidget);//标题头在最上面
		_tableWidget = new QTableWidget;
		_layout->addWidget(_tableWidget);
		this->setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint);//去掉系统标题头
	}
	~TestTitleWidget() 
	{
    
    

	}
private:
	QVBoxLayout *_layout;
	QTableWidget *_tableWidget;
	FCustomTitleWidget* _titleWidget;
 };
int main(int argc, char *argv[])
{
    
    
    QApplication a(argc, argv);
	TestTitleWidget loginWidget;
	loginWidget.show();
    return a.exec();
}

Enlace de código

Porque la velocidad de Internet de muchas personas en GitHub es muy lenta. Entonces, el código está alojado en Gitee .
Tenga en cuenta que el
código no es un proyecto completo. Solo hay archivos .hy archivos .cpp. El nombre del archivo es FCustomTitleWidget.h y FCustomTitleWidget.cpp
dirección de git
https://gitee.com/zmf199785/csdncode.git el
código de la FCustomTitleWidget directorio

Supongo que te gusta

Origin blog.csdn.net/weixin_39308337/article/details/111401622
Recomendado
Clasificación