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++程序媛~

相关推荐
风逸hhh1 小时前
python打卡day46@浙大疏锦行
开发语言·python
火兮明兮1 小时前
Python训练第四十三天
开发语言·python
ascarl20102 小时前
准确--k8s cgroup问题排查
java·开发语言
fpcc3 小时前
跟我学c++中级篇——理解类型推导和C++不同版本的支持
开发语言·c++
莱茵菜苗3 小时前
Python打卡训练营day46——2025.06.06
开发语言·python
爱学习的小道长3 小时前
Python 构建法律DeepSeek RAG
开发语言·python
luojiaao3 小时前
【Python工具开发】k3q_arxml 简单但是非常好用的arxml编辑器,可以称为arxml杀手包
开发语言·python·编辑器
终焉代码4 小时前
STL解析——list的使用
开发语言·c++
SoFlu软件机器人4 小时前
智能生成完整 Java 后端架构,告别手动编写 ControllerServiceDao
java·开发语言·架构
英英_4 小时前
视频爬虫的Python库
开发语言·python·音视频