亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

Qt股票組件之自選股列表拖拽、右鍵常用菜單功能的實現

2020-01-26 13:26:05
字體:
來源:轉載
供稿:網友

一、開頭嘴一嘴

本文帶領大家來看看自選股列表的實現。

如果有需要的朋友可以加我好友,有償提供源碼、或者也可以進一步提供功能定制

封裝的控件,或者demo都是沒有樣式的,所以看著會比較丑一些,不過加樣式也是分分鐘。。。這里咱可以先看功能,需要即可定制

本篇文章的自選股和大多數炒股軟件一樣,每一條自選都是支持拖拽的,拖拽時鼠標會跟隨一個拖拽映像,并且鼠標移動時,會有拖拽提示,告知我們鼠標釋放時拖拽項將會被插入到哪個位置。除過拖拽之外,自選股列表還支持右鍵菜單,都是一樣常用的操作。

右鍵菜單包括置頂、置低、刪除、下移一項、上移一項等

本篇文章中不包括的功能也可以提供定制,需求合理即可。

下面來具體說一說這個功能的實現思路,會公開大多數核心代碼,有需要的同學可以根據思路自行完善整個代碼。

二、效果展示

如下效果圖所示,是自選股使用上的一個展示效果,具有如下功能

1.搜索編輯框,支持股票代碼和股票名稱搜索
2.搜索預覽框支持鼠標hover,并且可以使用鍵盤上下鍵進行當前項切換,單機時支持切換自選股
3.自選股列表,支持拖拽,拖拽時會有拖拽項映像,并示意將要拖拽到哪個位置
4.支持右鍵菜單,可以對某一項進行移動,刪除等操作

如果覺著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::TopSotck); 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(OptionalMarketItemVector data){ d_ptr->m_bOnceLoad = true; disconnect(this, &QListWidget::currentItemChanged, this, &StockList::CurrentItemChanged); int i = 0; for (auto iter = data.begin(); iter != data.end(); ++iter, ++i) {  bool success = false;  if (QListWidgetItem * item = this->item(i))  {   if (ListItem * itemWidget = ItemWidget(item))   {    itemWidget->SetData(*iter);    success = true;   }  }  if (!success)  {   AddItem(*iter);  } } if (i < this->count()) {  QListWidgetItem * item = nullptr;  while (item = this->item(i))  {   if (ListItem * itemWidget = ItemWidget(item))   {    itemWidget->close();    itemWidget = nullptr;   }   item = takeItem(i);   delete item;  } } if (d_ptr->m_LeftPress == false) {  RecoveryCurrentItem(); } connect(this, &QListWidget::currentItemChanged, this, &StockList::CurrentItemChanged);}

總結

以上所述是小編給大家介紹的Qt股票組件之自選股列表拖拽、右鍵常用菜單功能的實現 ,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91成品人片a无限观看| 成人国产精品日本在线| 国产成人91久久精品| 欧美影院在线播放| 精品久久久91| 国产一区二区三区四区福利| 97在线视频精品| 国产精品久久二区| 国产精品第10页| 日韩av网站导航| 国产精品成熟老女人| 日韩av免费在线观看| 国产精品免费网站| 日韩美女视频免费看| 亚洲欧美日韩区| 日本欧美中文字幕| 疯狂做受xxxx高潮欧美日本| 国产精品一区av| 亚洲xxxx在线| 亚洲区一区二区| 久久久久国产视频| 国产成人综合久久| 45www国产精品网站| 欧美裸体xxxx| 欧美在线观看网址综合| 久久久精品一区二区| 超碰精品一区二区三区乱码| 国产精品爽黄69| 欧美大片免费观看在线观看网站推荐| 亚洲国产97在线精品一区| 一区三区二区视频| 日本中文字幕久久看| 欧美成aaa人片免费看| 国产91av在线| 成人激情视频小说免费下载| 久久精品国产久精国产一老狼| 国产精品91在线观看| 亚洲欧美日韩视频一区| 姬川优奈aav一区二区| 欧美极品xxxx| 亚洲精品一区二三区不卡| 日韩精品久久久久久久玫瑰园| 久久中文久久字幕| 久久资源免费视频| 有码中文亚洲精品| 精品视频偷偷看在线观看| 国产成人精品一区| 日韩在线免费高清视频| 91色视频在线导航| 成人亚洲综合色就1024| 欧美高清在线视频观看不卡| 中文字幕日韩专区| 上原亚衣av一区二区三区| 亚洲美女自拍视频| 国产香蕉一区二区三区在线视频| 日日狠狠久久偷偷四色综合免费| 91欧美精品成人综合在线观看| 国产成人高清激情视频在线观看| 亚洲免费成人av电影| 亚洲视频在线视频| 欧美有码在线观看| 综合激情国产一区| 91亚洲精品久久久久久久久久久久| 川上优av一区二区线观看| 欧美高跟鞋交xxxxxhd| 色偷偷av亚洲男人的天堂| 亚洲一级免费视频| 日韩久久精品电影| 国产精品久久久久久av福利软件| 九九热在线精品视频| 国内揄拍国内精品| 久久精品免费电影| 日韩欧美在线第一页| 2019中文字幕在线免费观看| 欧美片一区二区三区| 青青草99啪国产免费| 亚洲日韩中文字幕| 国产日韩欧美日韩大片| 亚洲a∨日韩av高清在线观看| 久久青草精品视频免费观看| 亚洲成人a级网| 久久久精品国产一区二区| 亚洲色图在线观看| 久久手机免费视频| 色综合视频网站| 在线播放国产一区中文字幕剧情欧美| 北条麻妃在线一区二区| 国产一区玩具在线观看| 国产日韩欧美视频在线| 色偷偷av一区二区三区乱| 国外视频精品毛片| 这里只有精品视频| 久久久久久一区二区三区| 成人在线视频福利| 亚洲大胆美女视频| 最新日韩中文字幕| 精品亚洲一区二区三区四区五区| 日韩av免费一区| 欧美在线观看日本一区| 国产精品久久久久久久7电影| 欧美巨大黑人极品精男| 久久久久999| 亚洲日本中文字幕| 欧美高清视频一区二区| 国产精品久久久久久久久久久不卡| 欧美日韩国产黄| 国产一区深夜福利| 国产亚洲精品日韩| 成人免费观看网址| 亚洲国产精品视频在线观看| 久久精品国产亚洲一区二区| 欧美激情国产精品| 日韩av片免费在线观看| 久久成人精品一区二区三区| 国产亚洲精品成人av久久ww| 亚洲色图校园春色| 亚洲欧美国产精品久久久久久久| 亚洲国产欧美一区二区三区久久| 97香蕉超级碰碰久久免费软件| 成人国内精品久久久久一区| 国产视频久久久久| 久久久久久亚洲精品中文字幕| 91爱爱小视频k| 日韩av毛片网| 欧美性感美女h网站在线观看免费| 亚洲精品国精品久久99热| 日本久久久久久| 成人自拍性视频| 午夜精品久久久久久久久久久久| 欧美成在线观看| 韩剧1988免费观看全集| 日韩欧美国产激情| 色噜噜狠狠色综合网图区| 精品国产欧美一区二区五十路| 久久精品亚洲94久久精品| 国内精品视频久久| 91在线观看免费高清完整版在线观看| 日韩中文字幕不卡视频| 欧美一级电影久久| 亚洲91av视频| 亚洲精品国产精品自产a区红杏吧| www国产亚洲精品久久网站| 精品亚洲男同gayvideo网站| 91经典在线视频| 欧美日韩美女在线| 色综合久久久888| 91色琪琪电影亚洲精品久久| 亚洲自拍偷拍区| 国产99久久精品一区二区 夜夜躁日日躁| 国产精品久久久久久久一区探花| 精品视频—区二区三区免费| 国产一区二区香蕉| 国产一区二区欧美日韩| 日韩欧美在线视频观看| 欧美在线视频导航| 欧美性生交大片免费| 国产精品狼人色视频一区| 国产亚洲欧洲高清一区| 欧美极品美女视频网站在线观看免费| 美女精品久久久| 久久男人资源视频| 欧美一级片一区| 国产精品男人爽免费视频1| 欧美电影免费观看大全|