在QT中无法直接修改右上角的最大最小化以及关闭按钮的样式,因此想对标题经行自定义往往采用隐藏标题栏,再通过QPushButton来模拟最大化,最小化,以及关闭功能。

        此时需要涉及几个问题:

        1.顶层窗口Qwidget窗口无法通过样式表设置边框圆角

        2.自定义QPushButton的样式,添加图标等

        3.由于我们把标题栏隐藏了。因此无法对窗口进行拖动操作,故要自己实现窗口的拖动功能

一、窗口边框圆角美化

        1.首先我们在目标窗口(如Mainwindow)的样式表中直接添加圆角、背景和边框的样式,例如:

//UI文件中,对最外层窗口的样式设置

QMainWindow{ /*类名*/

background-color:rgb(255, 85, 127); /*背景颜色(粉色)*/

border-radius: 10px; /*四角圆角的直径*/

border-style:solid; /*边框样式(实线)*/

border-width:2px; /*边框宽度*/

border-color:rgb(213, 213, 213); /*边框颜色*/

}

        此时运行发现,背景颜色溢出到四个圆角的边框外:

         2.在.cpp的构造函数中添加以下代码,将窗口设置为透明

setAttribute(Qt::WA_TranslucentBackground);//设置窗口透明化

        3.重写paintEvent(QPaintEvent *event)函数,在.h头文件中添加:

virtual void paintEvent(QPaintEvent *event) override; //重绘,

//需添加头文件

        在.cpp文件中:

void MainWindow::paintEvent(QPaintEvent *event)

{

QStyleOption opt;

opt.init(this);

QPainter painter(this);

style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);

}

//需添加头文件

        到此,圆角设置完成,运行:

        发现四个角依旧有黑色的底色,因为该Qwidget并非为最外层的,还有一层标题栏,我们在构造函数中添加如下代码把标题栏去掉:

this->setWindowFlags(Qt::FramelessWindowHint);//隐藏最大最小化等按键

        运行发现四边的黑色不见了,但是最上面有一条白线:

 

        这是mainToolBar的白线,可以直接在ui中将其删去。我在ui中把menuBar、mainToolBar、statusBar全都删去:

         最终圆角效果:

二、自定义标题栏

        1.在ui中添加如下结构的控件:

         把按键的文本删去,将控件放置于Widget的最顶部,稍微设置一下图标、颜色和按键效果等,最终效果如下:

 

三、窗口的拖动

        自定义标题栏时实现窗口拖动的大致过程:

        1.开启鼠标检测,检测鼠标左键点击的坐标是否为“标题栏”。若是,则将标志位设为真,然后记录下当前相对于屏幕的的全局坐标;若否,则将标志位置为假。

        2.当用户按住左键移动时,且标志位为真,则移动主窗口的位置到鼠标所在坐标。

        3.当用户释放鼠标时,将标志位置为假

        在头文件中添加如下代码,分别是鼠标按下触发,鼠标移动触发,鼠标释放触发:

virtual void mousePressEvent(QMouseEvent *event) override;

virtual void mouseMoveEvent(QMouseEvent *event) override;

virtual void mouseReleaseEvent(QMouseEvent *event) override;

        在.cpp中分别实现上述函数: 

void MainWindow::mousePressEvent(QMouseEvent *event)

{

int x=ui->widget->x();

int y=ui->widget->y();

int w=ui->widget->width();

int h=ui->widget->height();

//只能是鼠标左键移动和改变大小

if((event->button() == Qt::LeftButton) //处于左键状态

&&(event->x()>x&&event->x()

&&(event->y()>y&&event->y()

{

m_leftMousePressed = true; //标志位置为真

//按下时鼠标左键时,窗口在屏幕中的坐标

m_StartPoint = event->globalPos();

}

}

void MainWindow::mouseMoveEvent(QMouseEvent *event)

{

//移动窗口,由于取消了标题栏,因此需要自己实现拖动窗口功能

if (m_leftMousePressed)

{

QPoint curPoint = event->globalPos(); //按住移动时的位置

QPoint movePoint = curPoint - m_StartPoint; //与初始坐标做差,得位移

//普通窗口

QPoint mainWinPos = this->pos();

//设置窗口的全局坐标

this->move(mainWinPos.x() + movePoint.x(), mainWinPos.y() + movePoint.y());

m_StartPoint = curPoint;

}

}

void MainWindow::mouseReleaseEvent(QMouseEvent *event)

{

m_leftMousePressed = false;//释放鼠标,标志位置为假

}

        至此可实现窗口的拖动功能,同理可实现窗口的拖动缩放功能,本文不再赘述。

        窗口圆角参考此文:http://t.csdn.cn/aPNfX

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: