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 eventFilter
de 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