原文链接:Qt之股票组件-自选股--列表可以拖拽、右键常用菜单
一、开头嘴一嘴
上一篇文章Qt之股票组件-股票检索--支持搜索结果预览、鼠标、键盘操作讲述了股票检索功能,这篇文章我们来看看自选股列表的实现。
如果有需要的朋友可以加我好友,有偿提供源码、或者也可以进一步提供功能定制
封装的控件,或者demo都是没有样式的,所以看着会比较丑一些,不过加样式也是分分钟。。。这里咱可以先看功能,需要即可定制
本篇文章的自选股和大多数炒股软件一样,每一条自选都是支持拖拽的,拖拽时鼠标会跟随一个拖拽映像,并且鼠标移动时,会有拖拽提示,告知我们鼠标释放时拖拽项将会被插入到哪个位置。除过拖拽之外,自选股列表还支持右键菜单,都是一样常用的操作。
右键菜单包括置顶、置低、删除、下移一项、上移一项等
本篇文章中不包括的功能也可以提供定制,需求合理即可。
下面来具体说一说这个功能的实现思路,会公开大多数核心代码,有需要的同学可以根据思路自行完善整个代码。
二、效果展示
如下效果图所示,是自选股使用上的一个展示效果,具有如下功能
- 搜索编辑框,支持股票代码和股票名称搜索
- 搜索预览框支持鼠标hover,并且可以使用键盘上下键进行当前项切换,单机时支持切换自选股
- 自选股列表,支持拖拽,拖拽时会有拖拽项映像,并示意将要拖拽到哪个位置
- 支持右键菜单,可以对某一项进行移动,删除等操作
如果觉着demo比较丑的话,可以看财联社-产品展示这篇文章中的效果图
三、自选股列表
接下来就是我们这篇文章的重头戏了,也是比较复杂的一个内容。
自选股列表我选择的是使用QListWidget来实现,然后每一个item上在放一个Widget即可,Widget就是我们定制窗体内容,
这里我们主要讲解几个比较重要的核心内容
1、列表初始化
初始化StockList,实际上自选股列表应该从服务器拉取,我们这里作为demo测试,因此就自己模拟了5条数据进行插入。
//已选个股列表
d_ptr->m_pStockList = new StockList;
connect(d_ptr->m_pStockList, &StockList::RowClicked, this, [this](const QString & symbol){
emit RowClicked(symbol);
});
//测试数据 正常情况下 应该是列表自己拉取
OptionalMarketItem item;
for (int i = 1; i <= 5; ++i)
{
item.wstrSymbol = QString("0h000%1").arg(i).toStdWString();
item.wstrName = QString("%1%1%1").arg(i).toStdWString();
item.wstrIndustryName = QString("pingyin%1").arg(i).toStdWString();
d_ptr->m_pStockList->AddItem(item);
}
2、添加Item
往StockList中添加item项时,我们首先需要构造一个标准的QListWidgetItem结构,然后把我们自己定制的ListItem放到这个标准item结构上。
QListWidgetItem * StockList::AddItem(const OptionalMarketItem & data)
{
ListItem * itemWidget = new ListItem;
itemWidget->SetData(data);
QListWidgetItem * item = new QListWidgetItem;
addItem(item);
item->setSizeHint(QSize(0, 50));
setItemWidget(item, itemWidget);
return item;
}
ListItem就是一个普通的QWidget,上边排列了一些QLabel,用于显示我们的股票数据。
ListItem界面构造就不过多解释了,唯一需要说明的就是,我们股票数据发送变化时,界面上会有红绿色框的动画提示,这里需要调用两行代码来实现重新获取控件qss代码,并刷洗界面。
this->style()->unpolish(this);
this->style()->polish(this);
3、右键菜单
本篇文章和上一篇文章的右键菜单实现方式一样,都是参考我很早以前写的Qt之自定义QLineEdit右键菜单这篇文章,实现默认的contextMenuEvent函数即可。
右键菜单已经说的很多了,这里就一笔带过了,需要的同学可以自己快速的瞅一眼,应该比较容易理解。
void StockList::contextMenuEvent(QContextMenuEvent * event)
{
if (d_ptr->m_AllowMenu == false)
{
return;
}
if (d_ptr->m_ContextMenu == nullptr)
{
d_ptr->m_ContextMenu = new QMenu(this);
d_ptr->m_ContextMenu->setObjectName(QStringLiteral("StockListMenu"));
d_ptr->m_ContextMenu->setFixedWidth(100);
QAction * delAct = new QAction(QStringLiteral("删除自选股"), d_ptr->m_ContextMenu);
QAction * topAct = new QAction(QStringLiteral("置顶"), d_ptr->m_ContextMenu);
QAction * bottomAct = new QAction(QStringLiteral("置底"), d_ptr->m_ContextMenu);
QAction * upAct = new QAction(QStringLiteral("上移一位"), d_ptr->m_ContextMenu);
QAction * downAct = new QAction(QStringLiteral("下移一位"), d_ptr->m_ContextMenu);
connect(delAct, &QAction::triggered, this, &StockList::DeleteSotck);
connect(topAct, &QAction::triggered, this, &StockList::To