设为首页 加入收藏

TOP

Qt之股票组件-自选股--列表可以拖拽、右键常用菜单(二)
2019-07-09 08:11:01 】 浏览:166
Tags:股票 组件 选股 可以 常用 菜单
pSotck); connect(bottomAct, &QAction::triggered, this, &StockList::BottomSotck); connect(upAct, &QAction::triggered, this, &StockList::UpSotck); connect(downAct, &QAction::triggered, this, &StockList::DownSotck); d_ptr->m_ContextMenu->addAction(delAct); d_ptr->m_ContextMenu->addAction(topAct); d_ptr->m_ContextMenu->addAction(bottomAct); d_ptr->m_ContextMenu->addAction(upAct); d_ptr->m_ContextMenu->addAction(downAct); } d_ptr->m_ContextMenu->exec(mapToGlobal(event->pos())); QListWidget::contextMenuEvent(event); }

以上5个菜单,虽然看起来功能相差很多,但是其实处理逻辑基本都是一样的,先是一个内容结构排序,然后进行刷新数据到界面上。

为了节省篇幅,我这里就只介绍置顶一只股票的操作

置顶的逻辑看起来是这样的

  1. 移除当前项
  2. 并且把当前项item插入到新位置
  3. 构造一个新的Widget,设置给item
  4. 把新位置的item设置为当前选中项
  5. 上传最新列表到数据中心,或者服务器
void StockList::TopSotck()
{
    QListWidgetItem * item = currentItem();
    if (item == nullptr)
    {
        return;
    }

    if (row(item) == 0)
    {
        return;
    }

    ListItem * itemWidget = ItemWidget(item);
    QListWidgetItem * newItem = takeItem(row(item));
    insertItem(0, newItem);
    ListItem * topWidget = new ListItem;
    topWidget->SetData(itemWidget->GetData());
    setItemWidget(newItem, topWidget);

    if (itemWidget)
    {
        itemWidget->close();
        itemWidget = nullptr;
    }
    setCurrentItem(newItem);

    StorageData();
}

4、拖拽Item

拖拽Item应该算是一个比较难一点儿功能,好在Qt已经为我们实现了一套QDrag事件的回调方法,也比较好使,如下图所示,重写如下4个方法,基本的拖拽事件就能完成了。

但是这里我么有选择默认的这个回调函数来实现这个功能,其中最大的原因就是,他们的可定制性太局限了。

我这里采取的是自己模拟鼠标拖拽功能,同过重写如下几个函数来达到我的目的

virtual void mousePressEvent(QMouseEvent * event) override;
virtual void mouseMoveEvent(QMouseEvent * event) override;
virtual void mouseReleaseEvent(QMouseEvent * event) override;
virtual void enterEvent(QEvent * event) override;
virtual void leaveEvent(QEvent * event) override;
  1. 鼠标按下时,主要是记录了一些内容状态,方便在鼠标移动时去做判断,并决定是否启用鼠标拖拽功能
  2. 鼠标移动就比较复杂了,进行了各种对比,还需要移动被拖拽项的映像位置,移动那一根水平线的位置
  3. 鼠标释放时,调整整个列表的内容
  4. 鼠标进入窗体时,显示水平标识线
  5. 鼠标离开窗体时,隐藏水平标识线

上边只是粗略的描述了这几个函数的功能, 因为函数实现体都比较长,因此这里我也是选择几个关键点来做以说明。

a、move函数

产生拖拽时,移动鼠标,我们需要处理很多事件,比如

1、初始化水平表示线和拖拽项映像

if (d_ptr->m_ShotLine == nullptr)
{
    InitShotLine();
}
if (d_ptr->m_ShotPicture == nullptr)
{
    InitShotLabel();
}

2、拖拽时修改鼠标状态

根据拖拽启动后,鼠标是否还在当前拖拽项上,设置鼠标的状态。

if (ListItem * newWidget = ItemWidget(d_ptr->dragItem))
{
    d_ptr->m_ShotPicture->move(QCursor::pos() - d_ptr->dragItemPos);
    d_ptr->m_DragRect = visualItemRect(d_ptr->dragItem);
    if (d_ptr->m_DragRect.contains(event->pos()) || event->pos().isNull())
    {
        if ((event->pos() - d_ptr->startPos).manhattanLength() > 5)
        {
            setCursor(Qt::ForbiddenCursor);
        }
    }
    else
    {
        setCursor(Qt::ArrowCursor);
    }
    if (d_ptr->m_ShotPicture->isHidden())
    {
        d_ptr->m_ShotPicture->show();
    }
}

b、release函数

鼠标释放时,把拖拽项移动到新的位置

if (ListItem * oldWidget = ItemWidget(d_ptr->dragItem))
{
    QListWidgetItem * newItem = new QListWidgetItem;
    ListItem * itemWidget = new ListItem;
    itemWidget->SetData(oldWidget->GetData());

    insertItem(insertPos, newItem);
    newItem->setSizeHint(QSize(0, 50));
    setItemWidget(newItem, itemWidget);

    setCurrentItem(newItem);

    oldWidget->deleteLater();
}

5、刷新数据

全量刷新数据。在原来的列表上刷新数据

当原始列表行数不够时,构造新的行

当原始列表函数多时,移除末尾多的行

void StockList::Update_p(Optional
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++程序的多文件组成 下一篇基数排序的优雅实现

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目