Qt实现改变无标题栏窗体大小及移动窗体

这篇具有很好参考价值的文章主要介绍了Qt实现改变无标题栏窗体大小及移动窗体。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.问题的提出

2.实现方法

3.存在的问题


1.问题的提出

一般情况下,当去掉窗体标题栏时,按住鼠标左键就无法实现拖动窗体;当去掉窗体标题栏时,窗体四周的边框也去掉了,此时按住鼠标左键拖动窗体四周边沿,无法实现鼠标拖动改变窗体大小。如下为Qt实现去掉窗体标题栏的代码:


	setWindowFlag(Qt::FramelessWindowHint);  // 去掉标题栏

现在的问题是:

  • 在去掉窗体标题栏的情况下,如何按住鼠标左键,实现鼠标拖动改变窗体大小?
  • 在去掉窗体标题栏的情况下,如何在窗体上按住鼠标左键,实现移动窗体?

2.实现方法

Qt中有个QSizeGrip类,可以很好解决1节提到的问题,关于该类的具体用法,参见Qt Assistant。

下面直接上代码:

.h文件如下:

#pragma once

#include <QtWidgets/QWidget>
#include "ui_QtGuiApplication2.h"

class QtGuiApplication2 : public QWidget
{
	Q_OBJECT

public:
	QtGuiApplication2(QWidget *parent = Q_NULLPTR);

private:  // virtual

	void mousePressEvent(QMouseEvent* event) override;

	void mouseReleaseEvent(QMouseEvent* event) override;

	void mouseMoveEvent(QMouseEvent* event) override;
private:
	Ui::QtGuiApplication2Class ui;
	bool m_bLeftMousePressed{ false };  // 鼠标左键是否被按下
	QPoint m_lastPoint;               // 鼠标上次按下的点
};

.cpp文件如下:

#include "QtGuiApplication2.h"
#include<QSizeGrip>
#include<QVBoxLayout>
#include<QFrame>
#include<QStatusBar>
#include<QMouseEvent>
QtGuiApplication2::QtGuiApplication2(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);

	setWindowFlag(Qt::FramelessWindowHint);  // 去掉标题栏

	QVBoxLayout* pMainWnd = new QVBoxLayout(this);
	setLayout(pMainWnd);

	auto pFrame = new QFrame(this);
	pFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	pMainWnd->addWidget(pFrame);
	
	QHBoxLayout* pBottomLayout = new QHBoxLayout(this);
	pMainWnd->addLayout(pBottomLayout);

	// 加一个水平弹簧,为了把后面的QSizeGrip挤到最右边
	auto horizontalSpacer = new QSpacerItem(193, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
	pBottomLayout->addItem(horizontalSpacer);

   // 创建QSizeGrip对象,该对象就是用来调整窗体大小的
	auto pSizeGrip = new QSizeGrip(this);
	pSizeGrip->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
	pBottomLayout->addWidget(pSizeGrip); // 将QSizeGrip对象加入窗体右下角

	// 也可以加入一个状态栏来实现拖动窗体右下角改变窗体大小
	//auto pStatusBar = new QStatusBar(this);
	//pStatusBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
	//pBottomLayout->addWidget(pStatusBar);
}

// 鼠标左键按下,准备移动窗体
void  QtGuiApplication2::mousePressEvent(QMouseEvent* event)
{
	if (Qt::LeftButton != event->button())
	{
		return;
	}

	m_lastPoint = event->globalPos();
	m_bLeftMousePressed = true;
}

// 移动窗体结束
void  QtGuiApplication2::mouseReleaseEvent(QMouseEvent* event)
{
	if (Qt::LeftButton != event->button())
	{
		return;
	}

	m_bLeftMousePressed = false;
}

// 开始移动窗体
void  QtGuiApplication2::mouseMoveEvent(QMouseEvent* event)
{
	auto curMousePt = event->globalPos(); // 注意:这里记录是窗体在屏幕上的坐标位置
	auto offsetPt = curMousePt - m_lastPoint; // 计算和上次移动点的坐标差值
	move(pos() + offsetPt);
	m_lastPoint = curMousePt;  // 记录本次窗体所在位置,以便下次计算位置
}

效果如下:

qt无标题栏窗口拖动,QT,鼠标左键拖动无标题栏窗体,左键拖动改变无标题栏窗体大小,QSizeGrip

图1

QSizeGrip对象在窗体中的位置如下:

qt无标题栏窗口拖动,QT,鼠标左键拖动无标题栏窗体,左键拖动改变无标题栏窗体大小,QSizeGrip

图2

说明:

  • Qt中的QDialog和QStatusBar类封装了 QSizeGrip对象,故上面代码也可以插入QStatusBar类到右下角来实现 QSizeGrip对象调整大小功能,即注释掉29~31行代码,取消34~36注释,实现同样功能。
  • Qt中的QDialog和QStatusBar类提供了setSizeGripEnabled(bool)方法用来设置是否启用QSizeGrip对象,默认是启用的,即右下角QSizeGrip对象是可见的。

3.存在的问题

       从图1可以看到,当按住鼠标左键拖动右下角的QSizeGrip对象以改变窗体大小,此时窗体大小确实改变了,但窗体也随之被移动了,也就是既改变了窗体大小也移动了窗体。原因是QSizeGrip对象必须响应鼠标移动事件才能改变窗体大小,与此同时窗体响应鼠标事件被移动。如何只保证改变窗体大小,而不移动窗体呢?此时必须从QSizeGrip类派生出自己的子类,代码如下:

mySizeGrip.h:

#pragma once

#include <QSizeGrip>
namespace Ui { class CMySizeGrip; };

class CMySizeGrip : public QSizeGrip
{
	Q_OBJECT

public:
	CMySizeGrip(QWidget *parent = Q_NULLPTR);
	~CMySizeGrip();
private:  // virtual

	void mousePressEvent(QMouseEvent* event) override;

	void mouseReleaseEvent(QMouseEvent* event) override;

	void mouseMoveEvent(QMouseEvent* event) override;

private:
	Ui::CMySizeGrip *ui;
	QPoint m_lastPoint;                 // 鼠标上次按下的点
	QWidget* m_pParent; // 父窗体,也就是要调节大小的窗体
};

mySizeGrip.cpp:

#include "mySizeGrip.h"
#include "ui_mySizeGrip.h"
#include<QMouseEvent>
#include<QApplication>
CMySizeGrip::CMySizeGrip(QWidget *parent)
	: QSizeGrip(parent)
{
	m_pParent = parent;
	ui = new Ui::CMySizeGrip();
	ui->setupUi(this);
}

CMySizeGrip::~CMySizeGrip()
{
	delete ui;
}
void  CMySizeGrip::mousePressEvent(QMouseEvent* event)
{
	if (Qt::LeftButton != event->button())
	{
		return;
	}

	m_lastPoint = event->globalPos();
}

void  CMySizeGrip::mouseReleaseEvent(QMouseEvent* event)
{

}
void  CMySizeGrip::mouseMoveEvent(QMouseEvent* event)
{
	auto curMousePt = event->globalPos();
	auto offset = curMousePt - m_lastPoint;
	m_lastPoint = curMousePt;

    // 调整父窗体大小
	m_pParent->resize(m_pParent->size().width() + offset.x(), m_pParent->size().height() + offset.y());
}

将前面第29行的:

auto pSizeGrip = new QSizeGrip(this);

改为:文章来源地址https://www.toymoban.com/news/detail-540632.html

auto pSizeGrip = new CMySizeGrip(this);

到了这里,关于Qt实现改变无标题栏窗体大小及移动窗体的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt程序设计-无边框可移动可拖拽调整大小窗体

    本文讲解Qt-无边框可移动可拖拽调整大小窗体。 通过鼠标的按下移动进行窗体的移动,拖拽调整窗体大小。 实现过程如下: 创建QWidget窗体,添加一个按钮控制窗体的关闭。

    2024年02月19日
    浏览(28)
  • Qt获取鼠标移动事件,窗口内任意位置按下鼠标左键拖动窗口

    重写窗口的两个事件函数mousePressEvent和mouseMoveEvent即可: 在mousePressEvent 中,按下鼠标左键时,记录窗口坐标,其中窗口坐标的计算是由鼠标事件获取到鼠标在整个屏幕中的坐标(ev-globalpos()),然后再使用pos()获取到鼠标在窗口内的相对位置,两者之差就是窗口在整个屏幕上

    2024年02月12日
    浏览(38)
  • Qt隐藏标题栏,鼠标实现窗口右下角放缩窗口

    重写鼠标移动事件就可以了,如果想实现其它位置的缩放,可以自己根据鼠标的位置来实现,思路都是一样的

    2024年02月13日
    浏览(32)
  • 2022-9-2 QT实现画板(能改变画笔大小,颜色)

    用QT实现画板功能,代码如下 首先是头文件部分代码 后面是mywnd.cpp部分的代码 最后是main.cpp部分的代码 下面是运行的内容    

    2024年02月13日
    浏览(34)
  • 如何用Qt实现一个无标题栏、半透明、置顶(悬浮)的窗口

    在Qt框架中,要实现一个无标题栏、半透明、置顶(悬浮)的窗口,需要一些特定的设置和技巧。废话不多说,下面我将以DrawClient软件为例,介绍一下实现这种效果的四个要点。 要点一:移除标题栏(去除关闭、最小化、最大化按钮) 在窗口的构造函数中设置窗口的样式,

    2024年02月19日
    浏览(27)
  • QT实现窗口大小随分辨率变化而变化

    先上三张效果图,分别是原窗口、等比放大窗口和等比缩小窗口。 实现原理,就是借用QGraphicsView的缩放功能来实现的,并且做好QGraphicsView的防锯齿设置,就能完美的适应各种不同分辨率的显示器上了。 分辨率转换原理,如果窗口需要放在大分辨率的显示器上,需要将原窗口

    2024年02月12日
    浏览(35)
  • QT中将 子窗口添加到父窗口中,并实现子窗口随父窗口大小伸缩。

    在主窗口的 ui中 在MW ui中,整一个layout部件; 以及主窗口的其他部件一起都在MW(MainWindow)中,首先进行局部布局; 然后, 点击 MW ui再次进行 水平/垂直/..布局:这步重要,否则,子窗口就无法跟随主窗口一起进行缩放。 在 mainwindow.cpp嵌入子窗口 ui-xxxLayout-addWidget(子窗口

    2024年02月11日
    浏览(28)
  • Qt 自定义窗口的标题栏,重写鼠标事件实现,关闭隐藏,最大化/最小化,重写窗口事件函数,实现鼠标选中边框拉大拉小,双击标题栏切换窗口最大化和最小化

    Qt 自定义窗口的标题栏,重写鼠标事件实现,关闭隐藏,最大化/最小化,重写窗口事件函数,实现鼠标选中边框拉大拉小,双击标题栏切换窗口最大化和最小化 1、main.cpp 2、widget.h 3、widget.cpp 4、效果展示 5、完成

    2024年02月16日
    浏览(41)
  • C# winform中无标题栏窗口如何实现鼠标拖动?

    在C#中,可以通过重写窗体的鼠标事件来实现无标题栏窗体的拖动。 具体步骤如下: 禁用窗体的默认标题栏:在窗体属性中设置FormBorderStyle为None。 重写鼠标事件:在窗体类中重写MouseDown、MouseMove和MouseUp事件。 定义变量存储鼠标点击时的坐标。 在MouseDown事件中记录鼠标的位

    2024年02月02日
    浏览(27)
  • [Qt]FrameLessWindow实现调整大小、移动弹窗并具有Aero效果

    我们知道QWidget等设置了 this-setWindowFlags(Qt::FramelessWindowHint); 后无法移动和调整大小,但实际项目中是需要窗口能够调整大小的。所以以实现FrameLess弹窗调整大小及移动弹窗需求,并且在Windows 10上有Aero效果。 先看一下效果: 大部分参考这个github。然后自己修改了一下,因为

    2024年02月14日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包