Qt|QWidget窗口支持旋转

功能实现:使用QWidget创建的窗口支持窗口旋转功能。

展示的示例中支持由水平方向旋转至垂直方向。至于其它角度旋转的问题,看完这篇文章后应该会很简单能实现的!

开发环境:win VS2019 + Qt 5.15.2

在实现之前也有想用使用 QPropertyAnimation类,用动画的方式实现,经过验证发现,动画类不支持在object中进行旋转操作,所以放弃!

所以,采用广大博友推荐的方式:QGraphicsView控制场景中的子窗口进行旋转。

那么重点:如何让QWidget嵌入到QGraphicsView中并进行旋转。

首先,分享下实现出来的效果,如果需要这样的功能,大家可以继续看下去了~

当前的GIF效果只是展示了旋转功能的使用,具体项目中的业务,大家可以根据自己的情况进行修改,但是核心不变。

功能实现

开发环境:windows环境下 VS2019+5.15.2

当前窗口已经使用QWidget开发完成,此时,使用QGraphicsScene类将所有的窗口添加进去,能够快速进行旋转。

在当前demo中旋转父窗口是:QtRotateWidget,并且在该类中所有的子窗口需要使用QWidget继承实现,不要使用QDialog作为父类,否则无法进行控制!

demo涉及的子类包括:

QParentContentWidget:当前类属于父类,承载所有子窗口,相当于画布,每次旋转的时候,只是旋转的是子窗口的位置。

1:创建旋转画布

在QParentContentWidget窗口中Qt Designer中拖出来"graphicsView"控件,用于承载旋转画布。

1.1:设置视图区域

下面代码表示视图的大小与窗口大小一致。

cpp 复制代码
int nWidgetW = this->rect().width();
int nWidgetH = this->rect().height();
ui.graphicsView->setGeometry(0, 0, nWidgetW, nWidgetH);
ui.graphicsView->setFixedSize(nWidgetW, nWidgetH);

1.2:视图绑定场景

为了方便查看,给场景设置了一个背景色

cpp 复制代码
//创建视图
QSize sizeView = ui.graphicsView->size();
m_pScene = new QGraphicsScene(this);
m_pScene->setSceneRect(0, 0, sizeView.width(), sizeView.height());
m_pScene->setBackgroundBrush(QColor(255, 0, 0));
ui.graphicsView->setScene(m_pScene);

到这里,会有一个这样的问题:设置了视图与窗口大小相同时,为什么视图会出现滚动条

该如何解决这个问题呢?

我们需要给视图graphicsView隐藏垂直和水平滚动条,并且禁用滚动条,就好了

cpp 复制代码
//禁用滚动条
ui.graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui.graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui.graphicsView->horizontalScrollBar()->blockSignals(true);
ui.graphicsView->verticalScrollBar()->blockSignals(true);

此时,运行代码就会发现,不会再出现滚动条了!

2:创建子窗口

在前面我已经提到过,想要让窗口同步旋转,必须在创建窗口时,使其父类是:QWidget。因为QDialog窗口时阻塞的,对于一些实时弹出的窗口,每次在exe()之前都需要计算位置,很麻烦,不如QWidget的子类好控制。

下面,就以QChildWidget_Title类为例子,进行讲解。

创建出子类后,想要让子窗口随着父窗口的变化而变化,就需要在子类中响应"resizeEvent"函数。

cpp 复制代码
virtual void resizeEvent(QResizeEvent* event);


//实现
void QChildWidget_Title::resizeEvent(QResizeEvent* event)
{
	QWidget::resizeEvent(event);
    //根据新的窗口的宽度、高度,修改当前窗口中的控件
	this->UpdateControlRect(event->size().width(), event->size().height());
}

3:子窗口绑定旋转

子窗口被创建后,接下来就需要在视图中进行绑定。

3.1:添加需要展示的子窗口

在QParentContentWidget类中添加需要展示的子窗口。

cpp 复制代码
//创建,标题窗口
m_pTitleWidget = new QChildWidget_Title;

注意:在平时创建子窗口时,都会将父指针传入到构造中,此时,需要注意了,想要将子窗口绑定场景中,在创建子窗口时,不需要传入父指针。

3.2:将子窗口添加到场景中

cpp 复制代码
m_pProxyTitle = m_pScene->addWidget(m_pTitleWidget); //设置:标题栏

3.3:父窗口旋转

cpp 复制代码
void QParentContentWidget::ChangeScreenRotationStyle(bool bUseRotate)
{
	QSize sizeView = ui.graphicsView->size();
	int nNewWidth = 0, nNewHeight = 0;
	switch (m_enumWidgetStyle)
	{
	case WidgetStyle_Horizontal: //水平风格
	{
		if (bUseRotate == true)
		{
			ui.graphicsView->rotate(90);
		}
		nNewWidth = sizeView.width();
		nNewHeight = sizeView.height();
	}
		break;
	case WidgetStyle_Vertical: //垂直风格
	{
		if (bUseRotate == true)
		{
			ui.graphicsView->rotate(-90);
		}
		nNewWidth = sizeView.height();
		nNewHeight = sizeView.width();
	}
		break;
	}

	m_pScene->setSceneRect(0, 0, nNewWidth, nNewHeight);//设置原点和scene大小
	//设置:标题栏
	m_pProxyTitle->setGeometry(QRectF(0, 0, nNewWidth, 50));
	//设置:详情按钮
	int nBtnDetailsLeft = nNewWidth - 60 - 40;
	m_pProxyBtnDetails->setGeometry(QRectF(nBtnDetailsLeft, 100, 60, 60));
	//设置:提示窗口(窗口固定大小是:400*200)
	int nTipsLeft = (nNewWidth - 400) / 2;
	int nTipsTop = (nNewHeight - 200) / 2;
	m_pProxyTips->setGeometry(QRectF(nTipsLeft, nTipsTop, 400, 200));
	//设置:编辑内容窗口(窗口固定大小是:600*500)
	int nEditLeft = (nNewWidth - 600) / 2;
	int nEditTop = (nNewHeight - 500) / 2;
	m_pProxyEdit->setGeometry(QRectF(nEditLeft, nEditTop, 600, 500));
}

3.4:销毁移出

在析构父窗口时,需要删除场景,此时应该先将子窗口进行移出,再进行销毁

cpp 复制代码
QParentContentWidget::~QParentContentWidget()
{
	//将所有的视图移出Scene中
	m_pScene->removeItem(m_pProxyBtnDetails); //按钮详情
	m_pScene->removeItem(m_pProxyTitle); //标题栏
	m_pScene->removeItem(m_pProxyTips); //错误提示框
	m_pScene->removeItem(m_pProxyEdit); //编辑窗口

	//删除所有子控件
	if (m_pTipsWidget)
	{
		delete m_pTipsWidget;
		m_pTipsWidget = nullptr;
	}
	if (m_pTitleWidget)
	{
		delete m_pTitleWidget;
		m_pTitleWidget = nullptr;
	}
	if (m_pEditWidget)
	{
		delete m_pEditWidget;
		m_pEditWidget = nullptr;
	}
	if (m_btnDetails)
	{
		delete m_btnDetails;
		m_btnDetails = nullptr;
	}

	delete m_pScene; //删除视图
}

以上就是使用graphicsView控件进行窗口旋转的功能了,如果有需要的,可以从以下链接中下载哟~

旋转QWidget窗口

我是糯诺诺米团,一名C++程序媛~

相关推荐
泡海椒1 小时前
内置SPI函数库详解:JQuick-Java Builtin工具类实战用法
java·开发语言·python
hqyjzsb1 小时前
零 AI 项目经验,学 Python 转型 AI 的正确顺序是什么?
开发语言·人工智能·python·算法·职场和发展·数据挖掘·数据分析
Keven_112 小时前
算法札记:ACM适用的很骚的C++语法(持续更新)
开发语言·c++
mengzhi啊2 小时前
QPluginLoader 动态 DLL 插件版,支持插件之间通信,广播。请求和应答
c++·qt
脉动数据行情12 小时前
C# 实现德指 DAX 期货 WebSocket 实时行情监听
开发语言·websocket·c#
大圣编蚕3 小时前
Java ByteArrayInputStream 详解:从入门到实战
java·开发语言·算法
菜鸟~noob2333 小时前
【电子战】第02篇:能量检测器 vs. 相关检测器【含matlab代码】
开发语言·matlab
OpenAnolis小助手4 小时前
一句话看透 JVM,SysOM 诊断 Skill 新增 Java 应用诊断能力
java·开发语言·jvm·阿里云·操作系统控制台·sysom
小玮看世界4 小时前
[Python]OD算法在OD实际运用转化参考清单
开发语言·python·算法
ForteScarlet4 小时前
Kotlin 2.4.20 现已发布,新特性多不多?
android·java·开发语言·开源·kotlin·jetbrains