Qt重画标题栏

1.      在头文件中添加下列三个函数
//鼠标点击标题栏,重新实现拖动操作
void mouseMoveEvent(QMouseEvent*event);
void mousePressEvent(QMouseEvent*event);
void mouseReleaseEvent(QMouseEvent*event);
 
2.      在头文件中添加下列三个槽函数
 
private slots:
    void actionMin();      //最小化窗口
    void actionMax();      //最大化窗口
    void actionClose();   //关闭窗口
 
3.在头文件中下列变量
 QPoint mousePosition;       //自己实现拖动操作
 bool isMousePressed;        //自己实现拖动操作
 QToolButton *minButton;    //最小化按钮
 QToolButton *maxButton;    //最大化按钮
 QToolButton *closeButton;  //关闭按钮
 QLabel *labelTitle;         //软件名称
 QLabel *iconLabel;          //软件图标
 bool maxNormal;              //判断是否最大化标志位
 QPixmap normalPix;           //缩小图标
 QPixmap maxPix;              //最大化图标
4.定义鼠标可拖动区域
 
/********************鼠标作用域******************/
using namespace std;
const static int posMinX=0;
const static int posMaxX=20000;
const static int posMinY=0;
const static int posMaxY=40;
 
5.在构造函数中添加进行初始化
minButton=new QToolButton(this);   //最小化按钮
maxButton=new QToolButton(this);   //最大化按钮
closeButton=new QToolButton(this); //关闭按钮
iconLabel=new QLabel(this);         //图标按钮
labelTitle=new QLabel(this);        //软件标题
int width=this->width();             //获取软件占得像素大小
this->setMinimumSize(900,600);      //设置最小窗口
this->resize(QSize(900,600));       //初始化窗口显示大小
this->setWindowFlags(Qt::FramelessWindowHint); //去掉标题栏
QDesktopWidget *desktop=QApplication::desktop();
this->move((desktop->width()-this->width())/2,
(desktop->height()-this->height())/2);  //程序显示在屏幕中间
 

 

 /****************加载图标*******************/
Qpixmap  closePix
=style()->standardPixmap(QStyle::SP_TitleBarCloseButton);
closeButton->setIcon(closePix); 
 
 
MaxPix
=style()->standardPixmap(QStyle::SP_TitleBarMaxButton);
maxButton->setIcon(maxPix);
 
 
QPixmap minPix =style()->standardPixmap(QStyle::SP_TitleBarMinButton);
minButton->setIcon(minPix);
 
 
normalPix =style()->standardPixmap(QStyle::SP_TitleBarNormalButton);
 
 
/*****************加载位置******************/
iconLabel->setGeometry(10,7,22,22);
labelTitle->setGeometry(34,4,120,30);
minButton->setGeometry(width-96,6,30,30);
maxButton->setGeometry(width-66,6,30,30);
closeButton->setGeometry(width-36,6,30,30);
 
 
/******************提示信息*****************/
minButton->setToolTip(tr("最小化"));
maxButton->setToolTip(tr("最大化"));
closeButton->setToolTip(tr("关闭"));
ui->actionConn->setToolTip(tr("打开串口"));
labelTitle->setText(tr("雷达"));

 

 

 

 /*****************添加背景颜色**************/    minButton->setStyleSheet("background-color:transparent;");
maxButton->setStyleSheet("background-color:transparent;"); closeButton->setStyleSheet("background-color:transparent;");
setWindowIcon(QIcon(":/new/prefix1/RES/radar.png"));
maxNormal=false;          //是否最大化
isMousePressed=false;     //鼠标是否被按下
 /******************信号与槽连接**************/
//最小化按钮
connect(minButton,SIGNAL(clicked(bool)),SLOT(actionMin()));            
//最大化按钮
  connect(maxButton,SIGNAL(clicked(bool)),SLOT(actionMax()));        
//关闭按钮  connect(closeButton,SIGNAL(clicked(bool)),SLOT(actionClose())); 
 
                         
QFont font("ZYSong",11);     //字体大小为宋体11号字体
labelTitle->setFont(font);   //设置字体
setPalette(QPalette(Qt::DownArrow));//设置背景色
setAutoFillBackground(true);
 
 
 
 
6.在函数中实现
/***************最小化************************/
void RadarWindow::actionMin()
{
    showMinimized();
}
 
 
/***************最大化************************/
void RadarWindow::actionMax()
{
    if(maxNormal)
    {
        this->showNormal();
        maxNormal=!maxNormal;
        maxButton->setIcon(maxPix);
    }
    else
    {
        this->showMaximized();
        maxNormal=!maxNormal;
        maxButton->setIcon(normalPix);
    }
}
 
 
/***************关闭************************/
void RadarWindow::actionClose()
{
    close();    //关闭
}
 
 
/***************鼠标移动********************/
void RadarWindow::mouseMoveEvent(QMouseEvent *event)
{
    if(maxNormal)
    {
        return;
    }
    if(isMousePressed==true)
    {
        QPoint movePot=event->globalPos()-mousePosition;
        move(movePot);
    }
}
 
 
 
/***************鼠标点击*******************/
void RadarWindow::mousePressEvent(QMouseEvent *event)
{
    mousePosition=event->pos();  //当鼠标单击窗体准备拖动时,初始化鼠标在窗体中的相对位置
    //只对标题栏范围内的鼠标事件进行处理
    if(mousePosition.x()<=posMinX)
    {
        return;
    }
    if(mousePosition.x()>=posMaxX)
    {
        return;
    }
    if(mousePosition.y()<=posMinY)
    {
        return;
    }
    if(mousePosition.y()>=posMaxY)
    {
        return;
    }
    isMousePressed=true;
}
 
 
/***************鼠标释放*******************/
void RadarWindow::mouseReleaseEvent(QMouseEvent *event)
{
    isMousePressed=false;
}
 
 
/***************自动保存******************/
void RadarWindow::on_pushButtonSave_clicked()
{
    if(!ok)
    {
        return;
    }
    if(ui->pushButtonSave->text()==tr("停止保存"))
    {
        ui->pushButtonSave->setText(tr("保存"));
        if(fileOk)
        {
            fileSave->close();
            delete fileSave;
            fileOk=false;
        }
    }
    else if (ui->pushButtonSave->text()==tr("保存"))
    {
        ui->pushButtonSave->setText(tr("停止保存"));
    }
}
 

7.在函数中实现将窗口画成圆角形窗口

/***************画图函数************************/
void MainWindow::paintEvent(QPaintEvent *)
{
    QBitmap objBitmap(size());              //生成一张位图
    QPainter painterBit(&objBitmap);       //在位图上绘画
    painterBit.fillRect(rect(),Qt::white);//填充位图矩形框
    painterBit.setBrush(QColor(0,0,0));    //位图上画圆角矩形
    painterBit.drawRoundedRect(this->rect(),10,10);
    setMask(objBitmap);                   //使用setMark过滤即可

}

效果如图下所示:


<think>好的,用户的问题是关于在Qt框架中处理对话框标题栏双击事件的方法,特别是在自定义标题栏的情况下。我需要结合之前的引用内容来给出解决方案。 首先,用户引用了两篇关于Qt自定义标题栏的文章,其中提到了如何实现双击事件。根据引用[1],titleBar类中重写了mouseDoubleClickEvent来处理双击,并调用了updateMaximize方法。引用[2]也提到鼠标双击标题栏切换窗口状态。这说明解决方案需要继承QWidget或相关类,重写鼠标双击事件,并关联到窗口的最大化/还原功能。 接下来,我需要考虑用户的具体需求:自定义标题栏,并处理双击事件。通常,自定义标题栏需要隐藏默认标题栏,所以需要设置Qt::FramelessWindowHint。但这样会导致失去默认的标题栏功能,所以必须自己实现。 步骤应该是这样的:创建一个自定义标题栏的类,继承自QWidget,并在这个类中处理鼠标事件。需要重写mouseDoubleClickEvent函数,当检测到双击事件时,触发窗口状态的变化。此外,还需要处理窗口的移动,可能需要重写mousePressEvent和mouseMoveEvent来允许拖动窗口。 另外,引用中提到了使用事件过滤器(eventFilter)来监测标题栏上的事件,这可能用于子控件的事件处理,比如按钮。但用户的问题主要在于双击标题栏,所以重点在mouseDoubleClickEvent的重写。 需要注意的还有,自定义标题栏需要添加到对话框的布局中,并确保其能够正确捕获鼠标事件。同时,最大化/还原的逻辑需要根据当前窗口状态来切换,比如使用showMaximized()和showNormal()方法。 可能还需要处理窗口的边框和可拖动区域,确保用户交互的流畅性。此外,样式表(QSS)可能用于美化自定义标题栏,但这可能不是用户当前问题的重点,但需要提到以确保完整性。 最后,用户可能需要代码示例来具体实现这些步骤,所以应该提供一个简单的示例,展示如何创建自定义标题栏类,处理双击事件,并集成到对话框中。</think>在Qt中实现自定义标题栏的双击事件处理,需结合事件过滤与窗口状态控制技术。以下是分步骤实现方案: ### 一、核心实现原理 1. 隐藏原生标题栏 ```cpp dialog->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); ``` 2. 创建自定义标题栏控件 ```cpp class CustomTitleBar : public QWidget { Q_OBJECT protected: void mouseDoubleClickEvent(QMouseEvent *event) override; }; ``` 3. 事件处理流程 $$事件捕获 \rightarrow 状态判断 \rightarrow 窗口变换$$ ### 二、完整实现代码 ```cpp // titlebar.h class CustomTitleBar : public QWidget { Q_OBJECT public: explicit CustomTitleBar(QWidget *parent = nullptr) : QWidget(parent) { // 初始化UI组件... parentWidget()->installEventFilter(this); } protected: void mouseDoubleClickEvent(QMouseEvent *event) override { if (event->button() == Qt::LeftButton) { QWidget *window = parentWidget(); window->isMaximized() ? window->showNormal() : window->showMaximized(); } QWidget::mouseDoubleClickEvent(event); } bool eventFilter(QObject *obj, QEvent *event) override { if (obj == parentWidget()) { if (event->type() == QEvent::WindowStateChange) { // 更新最大化按钮状态 } } return QWidget::eventFilter(obj, event); } }; ``` ### 三、关键实现细节 1. **事件传递机制**:通过`installEventFilter`监控父窗口状态变化[^1] 2. **坐标转换**:使用`mapToGlobal()`处理多屏显示场景 3. **边缘检测**:在窗口最大化时保留5px边框用于拖动调整 ```cpp if (window->isMaximized() && (event->globalPos().y() < 5 || event->globalPos().x() < 5)) { window->showNormal(); } ``` ### 四、进阶优化方案 1. 动画过渡效果: ```cpp QPropertyAnimation *animation = new QPropertyAnimation(window, "geometry"); animation->setDuration(200); animation->setEasingCurve(QEasingCurve::OutQuad); ``` 2. DPI适配: $$缩放比例 = \frac{屏幕逻辑DPI}{96}$$[^2]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值