説明
多くの場合、ヘッダーのスタイルをカスタマイズする必要があります。Qtで。システムに付属のタイトルヘッダーを削除した場合。その後、多くの属性が消えます。たとえば、フォームをドラッグアンドドロップすることはできません。マウスでウィンドウを拡大することはできません。
アイデアを大まかに実現する
水平レイアウトを追加します。内部には2つのQLabelと3つのQPushButtonがあります。2つのQLabelを使用して、アイコンとウィンドウのタイトルを表示します。3つのQPushButtonは非表示に対応します。ボタンを最大化して閉じます。
次に、マウスがフォームの端に近づいたら、マウスカーソルの形状を変更する必要があります。そして、あなたはフォームを伸ばすことができます。同時に、タイトル上でマウスを押すことでドラッグアンドドロップできます。このタイトルヘッダーは、QWidget * _ownerWidgetを内部的に維持します。実際、これはこのタイトルヘッダーの所有ウィンドウです。次に、イベントフィルタeventFilter
を使用して、マウスイベントなどのイベントを監視します。
実装コード
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);//安装事件过滤器
}
}
ドラッグアンドドロップの実装
マウスが押されたとき。マウスが押された位置を記録します。次に、マウスをドラッグして移動したときの最後の位置との差を記録します。次に、フォームの位置を変更します。
実装コード
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;
マウスカーソルを変更する
** _ ownerWidgetのプロパティを_ownerWidget->setAttribute(Qt::WA_Hover);
設定すると、マウスホバリングイベントを検出できます。次に、マウスが_ownerWidget **のどこにあるかを確認します。近くにある場合は、方向に応じてマウスカーソルの形状を変更します。
実装コード
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;
}
マウスストレッチフォーム
まず、マウスのドラッグの方向に応じてフォームの位置またはサイズを変更する方法を決定します。マウスが周りにないが、このタイトルのヘッダーにある場合。次に、フォームの位置を移動します。それがすべての周りにある場合。フォームの位置とサイズを変更する必要があります。作者はGIF制作ツールを持っていないからです。レンダリングは投稿されません。特定の効果は、ビジュアルスタジオで見ることができます。VisualStudioの周りにマウスを置きます。カーソルが変わったことがわかります。上の見出しをクリックした場合は、ドラッグアンドドロップして位置を変更します。ドラッグする場合。ストレッチしてフォームの位置を変更できます。
実装コード
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;
}
}
使用例
#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();
}
コードリンク
GitHubでの多くの人のインターネット速度が非常に遅いためです。したがって、コードはGiteeでホストされます。コードは完全なプロジェクトではない
ことに注意してください
。.hファイルと.cppファイルのみがあります。ファイル名はFCustomTitleWidget.hおよびFCustomTitleWidget.cppです。git
アドレス
https://gitee.com/zmf199785/csdncode.git
コードはFCustomTitleWidgetディレクトリにあります。