首页 > 其他分享 >QTreeView代理QStyledItemDelegate实现按钮的鼠标hover移动和点击响应

QTreeView代理QStyledItemDelegate实现按钮的鼠标hover移动和点击响应

时间:2024-09-14 16:48:40浏览次数:9  
标签:index hover QTreeView caseinfo value else toString QString QStyledItemDelegate

1.需求描述

QStyledItemDelegate实现按钮的点击和响应功能,鼠标移动到按钮上,也会显示tooltip提示信息

2.实现方法

(1)重写editorEvent函数,根据type类型触发不同的响应函数

为了实现按钮的响应,需要重写QStyledItemDelegate 类的editorEvent函数,并根据插入时设置进去的type类型,判断是什么类型,然后去触发不同鼠标消息。

bool TreeTaskDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    //QMouseEvent *pEvent = static_cast<QMouseEvent *> (event);
    //m_mousePoint = pEvent->pos();

    bool ret = false;
    // 还原鼠标样式
    QApplication::restoreOverrideCursor();

    QVariantMap var = index.data(Qt::UserRole).toMap();
    if (var.contains("type"))
    {
        QString strType = var.value("type").toString();
        if (strType == "0")
        {
            ret=TriggerCase(event, model, option,index);
        }
        else if (strType == "1")
        {
            ret=TriggerFolder(event, model, option, index);
        }
        else if (strType == "3")
        {
            ret=TriggerCamera(event, model, option, index);
        }
        else if (strType == "2")
        {
            ret=TriggerVideo(event, model, option, index);
        }
    }
    return QStyledItemDelegate::editorEvent(event, model, option, index);
}

(2)根据坐标和鼠标消息类型响应不同的鼠标消息

还是以案件的触发来举例说明如何实现,根据绘制的按钮的坐标数据(要和paintCase函数中的按钮坐标一致),当鼠标在绘制的按钮矩形上移动时,触发QEvent::MouseMove信号,显示tooltips提示信息,一定要将QTreeView的mousetracing属性设置为true,否则无法触发QEvent::MouseMove信号;

点击按钮时触发MouseButtonRelease信号,根据坐标矩形区域判断是否点击了哪个按钮,向外发送按钮点击信号;

bool TreeTaskDelegate::TriggerCase(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    bool ret = true;
    QMouseEvent *pEvent = static_cast<QMouseEvent *> (event);
    if (pEvent == NULL)
    {
        return true;
    }
    QVariantMap info = index.data(Qt::UserRole).toMap();
    m_mousePoint = pEvent->pos();
    QRect rectItem = option.rect;
    QRect rectTop = QRect(rectItem.x() + 75, rectItem.y() + 8, 24, 24);
    QRect rectEdit = QRect(rectItem.x() + 95, rectItem.y() + 8, 24, 24);
    QRect rectCreateDir = QRect(rectItem.x() + 125, rectItem.y() + 8, 24, 24);
    QRect rectInput = QRect(rectItem.x() + 155, rectItem.y() + 8, 24, 24);
    QRect rectDelete = QRect(rectItem.x() + 185, rectItem.y() + 8, 24, 24);

    QRect rectState = QRect(rectItem.x() + 210, rectItem.y() + 10, 54, 20);
    QRect nameRect = QRect(rectItem.x() + 44, rectItem.y() + 8, 20, 24);
    switch (pEvent->type())
    {
        case QEvent::MouseButtonRelease:
        
        if (rectTop.contains(m_mousePoint))
        {
            emit signalBtClicked("0", "Top", index);
        }
        else if (rectEdit.contains(m_mousePoint))
        {
            emit signalBtClicked("0", "Edit", index);
        }
        else if (rectCreateDir.contains(m_mousePoint))
        {
            emit signalBtClicked("0", "CreateDir", index);
        }
        else if (rectInput.contains(m_mousePoint))
        {
            emit signalBtClicked("0", "Input", index);
        }
        else if (rectDelete.contains(m_mousePoint))
        {
            emit signalBtClicked("0", "Delete", index);
        }
        else if (rectState.contains(m_mousePoint))
        {
            emit signalBtClicked("0", "State", index);
        }
        break;
        case QEvent::MouseMove:
        {
            if (rectTop.contains(m_mousePoint))
            {
                if (info.contains("top") && info.value("top").toString() == "1")
                {
                    QToolTip::showText(pEvent->globalPos(), "取消置顶");
                }
                else
                {
                    QToolTip::showText(pEvent->globalPos(), "置顶");
                }
                
            }
            else if (rectEdit.contains(m_mousePoint))
            {
                QToolTip::showText(pEvent->globalPos(), "重命名");
            }
            else if (rectCreateDir.contains(m_mousePoint))
            {
                QToolTip::showText(pEvent->globalPos(), "创建子文件夹");
            }
            else if (rectInput.contains(m_mousePoint))
            {
                QToolTip::showText(pEvent->globalPos(), "导入");
            }
            else if (rectDelete.contains(m_mousePoint))
            {
                QToolTip::showText(pEvent->globalPos(), "删除");
            }
            else if (rectState.contains(m_mousePoint))
            {
                emit signalBtClicked("0", "State", index);
            }
            else if (nameRect.contains(m_mousePoint))
            {
                QToolTip::showText(pEvent->globalPos(), info.value("name").toString());
            }
            break;
        }
    }
    return ret;
}

(3)连接代理的鼠标点击信号和组织树的响应函数

connect(m_TreeDelegate, &TreeTaskDelegate::signalBtClicked, this, &TreeTaskList::SlotTreeBtClicked);

(4)实现按钮点击响应函数

根据delegate类传过来的信号type判断是案件、文件夹、监控点、视频任务;根据按钮类型判断是置顶、导入、删除等按钮;然后去处理不同的消息;

void TreeTaskList::SlotTreeBtClicked(QString type, QString bt, const QModelIndex &index)
{
    QVariantMap caseinfo = index.data(Qt::UserRole).toMap();
    QStandardItem*pItem = caseinfo.value("treeItem").value<QStandardItem*>();
    
    if (pItem==NULL)
    {
        LOG_ERROR("Btn Click pitem is NULL");
        return;
    }
    if (type=="0")//案件
    {    
        if (bt== "Top")
        {
            QString strTop =caseinfo.value("top").toString();
            if (strTop=="1")//取消置顶
            {
                caseinfo.insert("top", "0");
                QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
                caseinfo.insert("createtime", strTime);
                pItem->setData(strTime, QOrderRole);
                QString strSql = QString("update CaseManage set createtime = '%1' ,top='0' where path='%2'").arg(strTime).arg(caseinfo.value("path").toString());
                QString strmsg = "";
                QVariantMap result;
                LocalDb::instance()->ExcuateSql(strSql, result, strmsg);
                if (m_picPathDirInfo.find(caseinfo.value("path").toString()) != m_picPathDirInfo.end())
                {
                    m_picPathDirInfo[caseinfo.value("path").toString()]["createtime"] = strTime;
                    m_picPathDirInfo[caseinfo.value("path").toString()]["top"] = "0";
                }
                pItem->setData(caseinfo, Qt::UserRole);
            }
            else//置顶
            {
                caseinfo.insert("top", "1");
                //增加100年作为置顶时间排序最上面
                QString strTime = QDateTime::currentDateTime().addYears(100).toString("yyyy-MM-dd hh:mm:ss.zzz");
                caseinfo.insert("createtime", strTime);
                pItem->setData(strTime, QOrderRole);
                QString strSql = QString("update CaseManage set createtime= '%1' , top='1' where path='%2'").arg(strTime).arg(caseinfo.value("path").toString());
                QString strmsg = "";
                QVariantMap result;
                LocalDb::instance()->ExcuateSql(strSql, result, strmsg);
                if (m_picPathDirInfo.find(caseinfo.value("path").toString()) != m_picPathDirInfo.end())
                {
                    m_picPathDirInfo[caseinfo.value("path").toString()]["createtime"] = strTime;
                    m_picPathDirInfo[caseinfo.value("path").toString()]["top"] = "1";
                }
                pItem->setData(caseinfo, Qt::UserRole);
            }
            SlotUpdateTreeListBackground();
            m_modelTree->sort(0, Qt::DescendingOrder);
            
        }
        else if (bt== "Edit")
        {
            caseinfo.insert("editing", "Edit");
            pItem->setData(caseinfo, Qt::UserRole);
            ui.treeView->openPersistentEditor(index);
        }
        else if (bt== "CreateDir")
        {
            AddEmptyFoldToList(pItem);
            QModelIndex index = m_modelTree->indexFromItem(pItem);
            if (index.isValid())
            {
                ui.treeView->expand(index);
            }
        }
        else if (bt== "Input")
        {
            if (m_bAddingTaskToList)
            {
                emit signalError(-3, "正在批量导入任务,导入过程中不可用,请稍后重试");
                return;
            }
            
            m_pCurrentItem = pItem;
            if (m_pCurrentItem)
            {
                QString strParantPath = m_pCurrentItem->data(Qt::UserRole).toMap().value("path").toString();
                QString strType = m_pCurrentItem->data(Qt::UserRole).toMap().value("type").toString();
                if (strType == "0" || strType == "1")
                {
                    DLMgr::instance()->Fun_SetCurrentItemPath(strParantPath);
                }
            }
            m_iaddType = 1;
            emit signalAddAnaClicked(m_iaddType);
        }
        else if (bt== "Delete")
        {
            ConfirmDialog dig("删除案件将清空相关的数据和图片,确认删除?");
            if (dig.exec() == QDialog::Rejected)
            {
                return;
            }
            UpdateChildCheckState(pItem, true);
            QStringList listDelPicPath;
            QMap<QString, QVariantMap>taskInfos;
            BatchRecursiveDeleteItem(pItem, listDelPicPath, taskInfos);
            QString strPath = caseinfo.value("path").toString();
            if (strPath != "")
            {
                listDelPicPath.push_back(strPath);
                m_picPathDirInfo.remove(strPath);
            }
            DeleteCaseThread* pDelThread = new DeleteCaseThread();
            connect(pDelThread, &DeleteCaseThread::finished, pDelThread, [=]() {
                SlotUpdateTreeListBackground();
                UpdateAllCasesStatistic();
                pDelThread->deleteLater();
                emit signalSelectVedioChanged(m_mapStrFileSelected);
            });
            connect(pDelThread, SIGNAL(signalDelCollisionTask(QString)), this, SLOT(SlotDelCollisionTask(QString)));
            connect(pDelThread, &DeleteCaseThread::signalDeleteProgress, &m_progressDialog, &ProgressDialog::SlotDeleteProgress);
            pDelThread->SetDeleteCases(listDelPicPath, taskInfos);
            m_progressDialog.SlotDeleteProgress(0);
            m_progressDialog.exec();
            if (index.isValid())
            {
                m_modelTree->removeRow(index.row());
            }
            SlotUpdateTreeListBackground();
            UpdateAllCasesStatistic();
            emit signalSelectVedioChanged(m_mapStrFileSelected);
        }
        else if (bt== "State")
        {
            TasksStatistic taskState = caseinfo.value("TasksStatistic").value<TasksStatistic>();
            m_CaseStateWidget.SetTasksStatistic(taskState);
            QPoint Point = QCursor::pos();
            m_CaseStateWidget.move(Point.x() + 10, Point.y() + 10);
            m_CaseStateWidget.hide();//先隐藏再显示,否则会出现在下面;
            m_CaseStateWidget.show();
            m_CaseStateWidget.setFocus(Qt::FocusReason::ActiveWindowFocusReason);
        }
    }
}

这样就实现了不同按钮点击和响应的的功能;

 

标签:index,hover,QTreeView,caseinfo,value,else,toString,QString,QStyledItemDelegate
From: https://www.cnblogs.com/bclshuai/p/18414306

相关文章

  • QTreeView代理QStyledItemDelegate实现按钮、图标的绘制
    1.需求描述代理实现按钮图标状态的绘制实现方法(1)重写paint函数,根据type类型绘制案件、文件夹、监控点、视频任务; 为了实现不同的item的样式,需要继承QStyledItemDelegate类型实现TreeTaskDelegate。重写paint函数,根据不同的类型type去绘制不同的按钮和状态;voidTreeTaskD......
  • WPF 模仿前端大佬写一个Hover效果
    先看一下效果吧: 原博主的地址:【动画进阶】神奇的卡片Hover效果与Blur的特性探究-ChokCoco-博客园(cnblogs.com)原效果是一个css效果,我们采用WPF的方式模仿一下因为技术有限,没有原博主的那么好看,毕竟盗版永远比不过原版...然后这里看一下盗版的怎么写吧先是拿到......
  • 文字下滑线渐变效果(有hover效果)
    文字下滑线渐变效果(有hover效果)利用线性渐变,先设置background-size款为0,搞为3px,transition设置过过渡时间,hover时,把background-size宽度设为100%,高度还是3px<p>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<a>BBBBBBBBBBBBBBBBBBBBB......
  • html+css 实现hover 故障效果按钮
    前言:哈喽,大家好,今天给大家分享html+css实现hover故障效果按钮!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦......
  • KingbaseES V8R6集群运维案例之---switchover切换repmgr版本错误
    案例说明:KingbaseESV8R6集群,执行switchover切换时,报错“unabletoparse'repmgr's'rportedversion..."。适用版本:KingbaseESV8R6**一、问题现象**如下所示,执行switchover切换时,报错“unabletoparse'repmgr's'rportedversion...":二、问题分析1、在集群节点执......
  • html+css 实现hover 边框变背景效果按钮
    前言:哈喽,大家好,今天给大家分享html+css绚丽按钮效果!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦......
  • 【动画进阶】神奇的卡片 Hover 效果与 Blur 的特性探究
    本文,我们将一起探讨探讨,如下所示的一个卡片Hover动画,应该如何实现:这个效果的几个难点:鼠标移动的过程中,展示当前卡片边缘的border以及发光效果;效果只出现在鼠标附近?这一块的实现方法就有很多种了,可以计算鼠标附近的范围,在范围内去实现的效果,但是这样成本太高了。转换一......
  • QSortFilterProxyModel和QTreeView排序功能
    1、需求,创建一个树有多层结构,同一层按照插入顺序逆序排列; ui.treeView->setHeaderHidden(true);//treewidget头标题是否显示,此处隐藏标题//ui.treeWidget->header()->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);ui.treeView->header()->s......
  • html+css 实现hover中间展开背景
    前言:哈喽,大家好,今天给大家分享html+css绚丽效果!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦......
  • html+css 实现hover边框2边生长按钮
    前言:哈喽,大家好,今天给大家分享html+css绚丽效果!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦......