Qt quick实现无边框可拖拽风格

本文介绍了如何使用Qt Quick创建无边框窗口并实现拖拽功能。通过设置窗口标志、处理WM_NCHITTEST消息以及利用nativeEvent方法,解决了窗口拖拽时的延迟和鼠标移出问题。同时,将C++类导出到QML中,方便在QML界面中使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由来:

    现在大量的软件采用简洁的风格,即移除系统的标题栏及边框并自己实现标题栏以达到定制的目的,由于我们写要用Qt写一个类似IM的软件,故有此需求。

方法:

去除系统边框比较简单,setFlags(Qt::Window | Qt::FramelessWindowHint);即可,但下一步要实现窗体的拖拽和缩放。

1,最简单的方法:

    这种方法比较简单直观,即点击鼠标的时候记录下鼠标位置,然后在鼠标移动的时候对窗体进行移动。示例代码如下:

 MouseArea { //为窗口添加鼠标事件
    property int xMouse //存储鼠标x坐标
    property int yMouse //存储鼠标y坐标
    anchors.fill: parent
    acceptedButtons: Qt.LeftButton //只处理鼠标左键
    drag.filterChildren: true
    onPressed: { //接收鼠标按下事件
        xMouse = mouse.x
        yMouse = mouse.y
    }
    onPositionChanged: { //鼠标按下后改变位置
        loginScreen.x = loginScreen.x + (mouse.x - xMouse)
        loginScreen.y = loginScreen.y + (mouse.y - yMouse)
    }
}

    以上方法简单直观,但当窗体比较复杂的时候将发生窗体移动比较迟钝,甚至,当从上标题快速拖拽窗体时,鼠标移出窗体,而窗体不再移动的问题。
    网上的一个案例,大家可以参考http://blog.sina.com.cn/s/blog_a6fb6cc90101au8r.html

2,改进方案:

    观察系统默认的带标题栏的窗体,发现,拖动窗体时,窗体并不移动,而是由一个矩形框随着鼠标移动,当松开鼠标后窗体才进行一次性地移动。
    于是,有了一个可行的方案(因为后面有更优的方案,但是如果后面的方案不行,这个方案可能成为最后的方案),当拖拽的时候绘制一个移动的和原窗体等大小的矩形进行移动,最后再一次性地移动(相信系统的拖拽也是采用类似的方案)。具体实施略,可以自行测试。

3,继续改进方案,应该是一个较优方案:

    具体原理我也是参照这个博客http://blog.sina.com.cn/s/blog_6288219501015dwa.html,讲得比较详细,虽然是mfc程序,但毕竟也是windows程序,原理相同。
    摘抄一段:

当窗口确定鼠标位置时,Windows向窗口发送WM_NCHITTEST消息,可以处理该消息,使得只要鼠标在窗口内,Windows便认为鼠标在标题条上。这需要重载CWnd类处理WM_NCHITTEST消息的OnNcHitTest函数,在函数中调用父类的该函数,如果返回HTCLIENT,说明鼠标在窗口客户区内,使重载函数返回HTCAPTION,使Windows误认为鼠标处于标题条上。

UINT MyWndDlg::OnNcHitTest(CPoint point)
{
    // 取得鼠标所在的窗口区域
    UINT nHitTest = CDialog::OnNcHitTest(point);

    // 如果鼠标在窗口客户区,则返回标题条代号给Windows
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值