Qt实现Metro风格界面:拖动无边框窗口

        Qt的GUI功能非常灵活,Metro风格也越来越受欢迎,那么如何使用Qt实现一个Metro风格的界面?

        有两点最重要:一是使用Metro风格的素材,二是加入Metro风格的控制。博主近期将之前写过的一个Metro风格的框架开源了,你只需要下载源码,继承QMetro类就可以实现自己的Metro风格界面了。首先,确保你的Qt版本在5.2以上,那么,我们开始吧。

        特别提醒,在使用博主代码前,你需要添加几个图标ico资源,因为博主使用的Metro素材包受版权限制不能放在开源平台上,所以你的代码回提示缺少资源或者按钮图标显示不出来等等,你最好看下代码,就是最大化、最小化、任务栏托盘那几个图标。

        打开工程,其实会发现里面有四个类:QMetro、QMetroWindow、QDialog、QMetroMainWindow,首先说明这四个类的关系:

        QMetro->QMetroWindow->QDialog

                         QMetroWindow->QMetroMainWindow

        就是说QDialog类和QMetroMainWindow类都继承自QMetroWindow类。

        QMetro类是一个可以拖动,但无法改变大小的对话框,这个对话框就是去掉了一般对话框的边框,加入了鼠标事件。

        QMetroWindow是一个可以拖动,也可以改变大小的对话框,右上角加入了Metro风格的按钮。

        QDialog类是一个可以拖动,可以改变大小的对话框,可以在构造时传入参数选择不同的Metro风格。

        QMetroMainWindow类是一个主对话框类,其添加了全盘按钮,并且运行时会有任务栏托盘,最小化是会最小化到托盘。如果你用到这个类,你最好添加素材选择任务栏托盘图标,否则任务栏只会有提示文字而看不到托盘图标。

        全部的代码在博主的github上,以下提供QMetro类的代码。

#include "qmetro.h"

QMetro::QMetro(QWidget *parent)
	: QMainWindow(parent)
{
	this->setWindowFlags(Qt::FramelessWindowHint);
	isLeftPressDown = false;
	hlSysLayout = new QHBoxLayout;
	hlSysLayout->addStretch(1000);//保证以后插入的按钮(最大化、最小化等)都显示在最右边
}

QMetro::~QMetro()
{

}

void QMetro::mousePressEvent(QMouseEvent *event)
{
	if (!isFullScreen())
	{
		switch (event->button()) {
		case Qt::LeftButton:
			isLeftPressDown = true;
			dragPosition = event->globalPos() - this->frameGeometry().topLeft();
			break;
		default:
			break;
		}
	}
}

void QMetro::mouseMoveEvent(QMouseEvent *event)//通过鼠标时间实现空白区域拖动
{
	if (!isFullScreen())
	{
		QPoint gloPoint = event->globalPos();
		QRect rect = this->rect();
		QPoint tl = mapToGlobal(rect.topLeft());
		QPoint rb = mapToGlobal(rect.bottomRight());

		if (!isLeftPressDown) {
			//this->region(gloPoint);
		}
		else {
				move(event->globalPos() - dragPosition);
				event->accept();
		}
	}

}

void QMetro::mouseReleaseEvent(QMouseEvent *event)
{
	if (!isFullScreen())
	{
		if (event->button() == Qt::LeftButton) {
			isLeftPressDown = false;
			{
				this->releaseMouse();
				this->setCursor(QCursor(Qt::ArrowCursor));
			}
		}
	}
}

void QMetro::createSystemButton(QPushButton* (&pushbutton), QIcon ico) //右上角的系统按钮,最大化,最小化等
{
	pushbutton = new QPushButton(this);
	pushbutton->setFlat(true);
	pushbutton->setMaximumSize(20, 20);
	pushbutton->setMinimumSize(20, 20);
	pushbutton->setIcon(ico);
	hlSysLayout->addWidget(pushbutton);
	hlSysLayout->addStretch(1);
	pushbutton->raise();
}

         最后还是特别强调下,中间一些资源相关的东西需要修改。

发表评论