<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
首先,我們來看以下實現的最終效果吧!
我覺得這並不是一個很難得問題,最近新招了一個應屆生,發現在實現上述效果時,被困擾住了,是不是剛剛接觸Qt的這種稍微有難度的介面時,都會有些無頭緒呢?
所以,我打算分享給大家實現的思路,以及會出現的問題,就我一個開發5年C++的員工而言,針對新手會遇到哪些不懂的問題。
當前的開發環境:win10 VS2017 + Qt5.14.2 x64
在實現過程中新手會出現的難點,如下
1:如何在QListWidget中新增帶有按鈕、文字等其它控制元件的一條資料?
2:選中每一條之後如何響應?QListWidget自帶的item響應為什麼不生效?
3:如何選中刪除按鈕並通知QListWidget做出具體的響應?
就根據上述三個問題,邊講述問題邊實現帶有自定義控制元件的Item內容吧!
在使用QListWidget插入一條資料時,預設的方式,如下:
ui.listWidget->insertItem(0, "Text Content"); //方法1 ui.listWidget->addItem("Text Content"); //方法2
使用上述程式碼是無法實現的,因為引數中只能新增QString型別的字串,那麼該如何實現新增自定義項呢?
在QListWidget類中提供了叫做QListWidgetItem的子類,用於實現自定義的item。
這時,我們就需要重新定義一個類,並且將該類與ListWidgetItem進行繫結,就可以實現每一行的item上展示屬於我們自定義的格式了。
例子中展示的item中顯示了一個選擇框、檔名稱以及刪除按鈕。
在這裡,採用了QCheckBox以及QPushButton兩個按鈕實現的。
有人會詢問:檔名稱不應該使用QLabel控制元件表示嗎?
回答是:當前可以使用QLabel控制元件顯示檔名稱,這裡採用QCheck主要是想要展示檔案的圖示,根據不同的檔名字尾顯示不同的圖示。
自定義Widget
該類繼承自QWidget。假設叫做:CustomItem
有些新手會直接建立一個純的C++類別,這樣做肯定是有問題的,當我們在外部使用當前自定義類時,你會發現,為什麼新建立的類會單獨分出來呢?
如果直接使用純C++類別,還有另一個至關重要的問題,當前類需要進行訊息互動時,你該如何傳遞給外部呼叫者呢?回撥嗎?是不是有點大材小用呢?
class CustomItem : public QWidget { Q_OBJECT public: CustomItem(QWidget *parent); ~CustomItem(); private: QCheckBox* m_checkName; //檔名 QCheckBox* m_checkSelect; //選擇 QPushButton* m_btnDelete; //刪除 };
自定義類CustomItem中建立了三個控制元件變數,分別表示了:選擇框、檔名稱以及刪除按鈕。
就是文章開始顯示效果圖的三個控制元件了。
接下來,需要定義一個外部呼叫介面,插入一條有效資料,假設介面名稱是:AddINewtemData
class CustomItem : public QWidget { Q_OBJECT public: CustomItem(QWidget *parent); ~CustomItem(); public: //對外開放介面 void AddINewtemData(int nRow, QString qsFileName); //新增一條新資料 private: int m_nRow; QCheckBox* m_checkName; //附件名 QCheckBox* m_checkSelect; //選擇 QPushButton* m_btnDelete; //刪除 };
AddINewtemData 引數
引數1:代表的是當前自定義widget屬於QListWidget的行編號,用於後續訊息傳遞使用。
引數2:需要展示的檔名稱
根據使用者傳入的檔名稱,根據檔案字尾展示不同的圖示。
void CustomItem::AddINewtemData(int nRow, QString qPath) { m_nRow = nRow; //記錄當前自定義widget對應的QListWidget的行號 //根據路徑名,獲取檔名稱,並設定 QFileInfo info(qPath); QString qsFileName = info.fileName(); m_checkName->setText(qsFileName); //獲取檔案字尾 QString qsCheckStyle = ""; if (info.suffix() == "mp4") //視訊檔 { //自定義QCheckBox風格 } else if (info.suffix() == "png") //圖片檔案 { //自定義QCheckBox風格 } else if (info.suffix() == "xlsx") //表格檔案 { //自定義QCheckBox風格 } else if (info.suffix() == "pdf") { //自定義QCheckBox風格 } else //檔案檔案 { //自定義QCheckBox風格 } m_checkName->setStyleSheet(qsCheckStyle); }
構造完自定義widget類之後,接下來就需要將該類與QListWidgetItem進行繫結,顯示到QListWidget上去。
外部呼叫方法,如下:
int nCount = ui.listWidget->count(); CustomItem* widget = new CustomItem(this); widget->AddINewtemData(nCount, qsFileName); widget->show(); QListWidgetItem* item = new QListWidgetItem; item->setSizeHint(QSize(48, 48)); ui.listWidget->addItem(item); ui.listWidget->setItemWidget(item, widget);
自定義CustomItem響應
上述功能可以實現QListWidget中展示自定義的widget之後,該如何點選QListWidget中的每一條做出不同的響應呢?
此時,我們對每一行的QListWigetItem繫結自定義類之後,是無法響應QListWidget自身的選擇訊息的!這一點需要大家記清楚了。
那麼,該怎麼觸發呢?
針對於每一個QWidget類,只要是繼承自QWidget,都會有滑鼠的四大響應:
virtual void mousePressEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event); virtual void mouseDoubleClickEvent(QMouseEvent *event); virtual void mouseMoveEvent(QMouseEvent *event);
當滑鼠在自定義類做了點選效果後,肯定可以在滑鼠按下事件中獲取點選響應的。
所以,在自定義類CustomItem中需要重寫QWidget的系統訊息:mousePressEvent
void CustomItem::mousePressEvent(QMouseEvent *event) { QWidget::mousePressEvent(event); }
斷點設在該響應函數中時,肯定是會觸發的,如果不可以肯定是當前widget處於禁用狀態,或者是被遮蓋住了。
這裡還有一個隱藏問題:有些同學在點選自定義視窗時會發現這樣一個奇怪的現象,為什麼點選有些區域是響應mousePressEvent訊息的,而點選有些區域是不響應呢?
以下是重中之重了!!
這就是前一段話提到的內容了,當前widget不觸發時,肯定是禁用或者是被遮擋住了。
在我們這個自定義Widget中有三個活躍的控制元件,兩個QCheck,一個QPushButton,當我們的滑鼠在任意控制元件上點選時,此時的點選響應應該是響應到子控制元件上,而不是自定義的Widget(CustomItem)上。
為了讓滑鼠點選任何控制元件時,所有的響應都響應到父類別Widget,也就是CustomItem上時,我們應該對支援滑鼠響應操作的控制元件做特殊處理
setAttribute(Qt::WA_TransparentForMouseEvents)
每個控制元件都要設定以上的操作,當前控制元件只是用來顯示,不做任何訊息處理,是當前視窗做的訊息處理
自定義Widget控制元件響應並通知外界處理
下面,來說一說第三個重點問題,如何通知外界處理。
我們使用了自定義的Widget之後就不能再使用QListWidget的內部選中訊息了,為了讓外部視窗獲取內部Widget的訊息時,此時我們需要採用發訊號的方式,通知外界,模擬QListWidget訊息。
signals: void Msg_SendDeleteItemData
外部視窗直接操作該訊息,使用方法跟普通的方法一致,這裡就不再過多介紹Qt中訊息機制了。
以上實現QListWidget內嵌自定義視窗的核心功能就說清楚了。
到此這篇關於詳解QListWidget如何實現自定義Item效果的文章就介紹到這了,更多相關QListWidget自定義Item內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45