首页 > 其他分享 >Qt模仿多标签页窗口拖拽操作

Qt模仿多标签页窗口拖拽操作

时间:2023-08-24 19:11:26浏览次数:38  
标签:窗口 Qt 标签 newWnd 拖拽 drag event

本功能的实现主要依托于Qt的拖拽操作。从本文可以学到Qt的拖拽机制,自定义QMimeData的数据类型,和自定义的QGraphicsEffect效果。本文的视觉特效是应用于拖拽的时候指示当前鼠标的位置和拖拽结果新标签页会放置在当前窗口的第几个标签页之后。以下是窗口的效果图片,为了方便标签是用按钮做的。第一张图是主窗口截图:

第二张图是拖拽“第二页”拍摄的图(因为截屏截不到光标效果)。可以看到在“第四页”右侧有个倒三角形指示拖拽的新标签页将放在“第四页”右侧:

第三张图是拖拽“第二页”到任意地方拍摄的图片。此时松开鼠标“第二页”将变成一个独立的窗口:

第四张图是把“第四页”拖拽成独立窗口之后的效果图:

下面将给出拖拽部分的代码。之所以拖拽操作在eventFilter(...)函数里,是因为鼠标在按钮上面操作时父Widget是收不到鼠标消息的,因此用事件过滤器拦截按钮的消息。完整的项目在Github里开源了,链接是:<以后再补>:

bool MDragableCtrl::eventFilter(QObject* src, QEvent* event)
{
    if (event->type() == QEvent::MouseButtonPress)
    {
        lastPt = dynamic_cast<QMouseEvent*>(event)->pos();
    }
    else if (event->type() == QEvent::MouseMove)
    {
        QMouseEvent* tempEvent = dynamic_cast<QMouseEvent*>(event);
        QWidget* thisWidget = dynamic_cast<QWidget*>(src);
        if ((lastPt - tempEvent->pos()).manhattanLength() < QApplication::startDragDistance() && 
            lastPt == QPoint(-1, -1))
        {
            return false;
        }
        int which = findHitButton(thisWidget->mapToParent(tempEvent->pos()));
        if (which >= 0)
        {
            dynamic_cast<QHBoxLayout*>(layout())->removeWidget(saveBtns[which]);delete saveBtns[which];
            saveBtns.removeOne(saveBtns[which]);

            QtMultiPageWnd* myself = dynamic_cast<QtMultiPageWnd*>(topLevelWidget());
            QWidget* movePage = myself->takePage(which);
            QtMultiPageWnd* newWnd = new QtMultiPageWnd(movePage);
            newWnd->move(2048, 2048); /* 不显示无法获取正确的frameGeometry()值 */
            newWnd->show();
            /* 空了先隐藏自己 */
            /* 拖拽结束再关闭自己,见下方代码 */
            if (empty())
            {
                myself->hide();
            }

            QDrag drag(this);
            QMimeData *mimeData = new QMimeData;
            mimeData->setData(u8R"(application/x-qt-windows-mime;value="QtMimeType")", QtMimeType(newWnd).toByteArray());
            drag.setMimeData(mimeData);
            drag.setPixmap(createWndSnapshot(newWnd));
            drag.setHotSpot(newWnd->mapToFrame(tempEvent->pos()));

            Qt::DropAction dropAction = drag.exec();
            if (dropAction == Qt::IgnoreAction)
            {
                newWnd->move(QCursor::pos() - drag.hotSpot());
            }
            /* 如果本窗口已经空了,则关闭自己 */
            /* 注意不能直接delete,万一本窗口是主窗口内存在栈上删除会报错 */
            if (empty())
            {
                myself->close();
            }
            return true;
        }
    }
    else if (event->type() == QEvent::MouseButtonRelease)
    {
        lastPt = QPoint(-1, -1);
    }
    return false;
}

 

标签:窗口,Qt,标签,newWnd,拖拽,drag,event
From: https://www.cnblogs.com/mengxiangdu/p/17650070.html

相关文章

  • zbar:Qt调用zbar做条码识别
    需求:Qt开发的一个程序,妹子总是说需要条码识别功能,没办法,只能加上这个功能 zbar编译:https://gitee.com/vvvj/zbar-windows 主要代码:#include"zbar.h"usingnamespacezbar;voidheihei::tool_tiaoma(){//qDebug()<<"条码===begin=====";QImageimg;......
  • Qt中的键盘事件和鼠标事件
    Qt是一个流行的C++框架,用于开发跨平台的应用程序。在Qt中,键盘事件和鼠标事件是实现交互性和响应性的重要部分。Qt中定义了多种键盘事件和鼠标事件,这些事件可以用于处理用户与界面的交互。下面将详细介绍常用的键盘事件和鼠标事件及其用途。一、键盘事件1.QKeyEventQKeyEvent是......
  • 删除文章里的中文符号和空格,换成英文逗号,并获取最后两个标签
    defupdate_biaoqian(tag_list,title):iflen(tag_list)==0:print('没有标签,取标题作为标签')titless=re.sub('\s',',',title)tag_list=title.replace('、',',').replace(';',......
  • BCEloss和多标签任务
    BCEWithLogLoss(BinaryCrossEntropywithLogLoss)和BCE(BinaryCrossEntropy)是两种常用的二分类损失函数,它们的区别主要在于损失函数的形式和计算方式上。BCEWithLogLoss是基于对数损失函数的二分类损失函数。它的计算公式为:BCEWithLogLoss(y,ŷ)=-y*log(ŷ)-(1-y)......
  • 手动将QT项目打包成exe(手动打包,不是CMake自动打包)
    综述:仅记录QT项目打包的过程。构建工具:CMake主要流程:确保项目软件可以正常运行。使用release生成发布文件夹。将发布文件夹中的运行文件和依赖文件打包到另一个文件夹中。步骤:一、确保项目软件可以正常运行。点击左下角的运行按键确保软件正常运行(如果不能正常运行,下......
  • element+Sortable 实现表格拖拽
    <template><divclass="draggable"style="padding:20px"><el-tablerow-key="id":data="state.tableData"style="width:100%"><el-table-columnv-for="(item,......
  • meta标签的作用是什么
    meta是用来在HTML文档中模拟HTTP协议的响应头报文。meta标签用于网页的<head>与</head>中,meta标签的用处很多。meta的属性有两种:name和http-equiv。name属性主要用于描述网页,对应于content(网页内容),以便于搜索引擎机器人查找、分类(目前几乎所有的搜索引擎都使用网上机器人自动查找me......
  • vuedraggable和vue-fragment冲突导致连续多次拖拽报错问题
    项目中使用了vuedraggable实现拖拽功能。同时为了不产生多余标签,引入了vue-fragment。在连续多次拖动之后,总是报错。 解决办法:卸载vue-fragment。如果不想引入多余的标签,可以直接使用<template>,而且<template>标签是标准的HTML标签,更具可移植性。......
  • Qt编写网易云界面 (5) -----专属定制和歌单实现
    今天主要完成专属定制和歌单部分,效果如图:UI部分:主要的qss:/*专属定制部分*/QLabel#lab_per{ font-family:"微软雅黑"; color:rgb(55,55,55); font-size:20px; font-weight:bold;}QLabel#lab_per2{ font-family:"微软雅黑"; color:rgb(159,159,159);}Q......
  • QTL
     QTL:是数量性状基因座:它指的是控制数量性状的基因在基因组中的位置。QTL实际上是一个抽象的概念。指的是存在与基因组中的某一位置,这个位置上的基因会影响某一数量性状的表达。QTL可以是一个简单的基因座,也可以是多个基因座的组合。......