一直都認為,用最通俗的語言,講解最深刻的技術,是每一個技術交流者應該考慮的事情,今天朋友問我,好友清單該怎麼實作。我想起之前上網查閱的時候,發現網上介紹這塊的内容甚少,而且講解的不夠好,于是,本着互相交流的精神,在這裡講解一下我是怎麼實作QQ好友清單的。
1、Q:關于好友清單到底是QTreeWidget/QTreeView還是QListWidget/QListView的問題?
A:相信大家初次一看,大部分都認為是QTreeWidget,其實是用QListWidget或者QListView均可簡單實作,在資料多的時候,QListWidget性能會降低,不過,對于好友清單來說,QListWidget足以,并且更加簡單。是以,我繼承的是QListWidget來實作。
2、Q:關于如何實作一個Item具有多種資訊,包括頭像、使用者名、個性簽名等?
A:該Item其實是一個繼承了QWidget的自定義buddy類,把你所想要的資訊全部在該buddy類裡面布局好,甚至可以加進按鈕,自定義的好處就在于,你想到什麼,就能幹什麼,然後在QListWiget裡面裡通過實作
[cpp] view plain copy
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5Gcu82Yp9VRE90Qvw1c0V2czF2LcRXZu5ibkN3YuUGZvN2Lc9CX6MHc0RHaiojIsJye.png)
- QListWidgetItem *newItem = new QListWidgetItem(); //建立一個newItem
- this->insertItem(row(currentItem)+tem.count(),newItem); //将該newItem插入到後面
- this->setItemWidget(newItem, buddy); //将buddy賦給該newItem
[cpp] view plain copy
- QListWidgetItem *newItem = new QListWidgetItem(); //建立一個newItem
- this->insertItem(row(currentItem)+tem.count(),newItem); //将該newItem插入到後面
- this->setItemWidget(newItem, buddy); //将buddy賦給該newItem
即可。
3、Q:關于如何實作好友的展開與隐藏?
A:這部分裡我設定了兩個容器:
[cpp] view plain copy
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5Gcu82Yp9VRE90Qvw1c0V2czF2LcRXZu5ibkN3YuUGZvN2Lc9CX6MHc0RHaiojIsJye.png)
- QMap<QListWidgetItem*,QListWidgetItem*> groupMap; // 組容器 - key:項 value:組
- QMap<QListWidgetItem*,bool> isHideMap;//用來判斷該組是否隐藏了
[cpp] view plain copy
- QMap<QListWidgetItem*,QListWidgetItem*> groupMap; // 組容器 - key:項 value:組
- QMap<QListWidgetItem*,bool> isHideMap;//用來判斷該組是否隐藏了
其中,groupMap用來存放key為項,value為組的資料,比如我增加了一個“我的好友”的組,則存進去是key:我的好友,value:我的好友;接着,在isHideMap存放key:我的好友,value:false,表示預設該組是未展開的;緊接着,如果在“我的好友”裡,我增加了一個好友“逍遙聖帝”,則存進去的是:key:逍遙聖帝,value:我的好友,這樣處理的關鍵是為了儲存好組與好友的關系;最後再利用isHideMap來判斷組的狀态,如果是隐藏,則通過周遊groupMap裡面的好友,使之顯示,否則,反之。
4、Q:關于如何實作美化效果?
A:直接用QSS就可以了。
下面直接貼出源代碼,我已經在源代碼裡面詳細給每一個關鍵步驟進行了說明,是以就不進行闡述了,相信大家看得懂的,如有不懂可以追加評論,第一時間回複你們,下面是實作一個QQ好友清單的簡單功能,對于其他功能大家好好拓展即可~~
一、首先是實作具有各種資訊的Buddy類:
personListBuddy.h
[cpp] view plain copy
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5Gcu82Yp9VRE90Qvw1c0V2czF2LcRXZu5ibkN3YuUGZvN2Lc9CX6MHc0RHaiojIsJye.png)
- #ifndef PERSONLISTBUDDY_H
- #define PERSONLISTBUDDY_H
- #include <QWidget>
- #include <QLabel>
- #include <QEvent>
- //自定義資訊Item類
- class personListBuddy : public QWidget
- {
- Q_OBJECT
- public:
- explicit personListBuddy(QWidget *parent = 0);
- void initUi();//初始化Ui
- QWidget *head; //頭像
- QLabel *name; //使用者名
- QLabel *sign; //個性簽名
- QString headPath;//頭像路徑
- bool eventFilter(QObject *obj, QEvent *event);//事件過濾器
- signals:
- public slots:
- };
- #endif // PERSONLISTBUDDY_H
[cpp] view plain copy
- #ifndef PERSONLISTBUDDY_H
- #define PERSONLISTBUDDY_H
- #include <QWidget>
- #include <QLabel>
- #include <QEvent>
- //自定義資訊Item類
- class personListBuddy : public QWidget
- {
- Q_OBJECT
- public:
- explicit personListBuddy(QWidget *parent = 0);
- void initUi();//初始化Ui
- QWidget *head; //頭像
- QLabel *name; //使用者名
- QLabel *sign; //個性簽名
- QString headPath;//頭像路徑
- bool eventFilter(QObject *obj, QEvent *event);//事件過濾器
- signals:
- public slots:
- };
- #endif // PERSONLISTBUDDY_H
personListBuddy.cpp
[cpp] view plain copy
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5Gcu82Yp9VRE90Qvw1c0V2czF2LcRXZu5ibkN3YuUGZvN2Lc9CX6MHc0RHaiojIsJye.png)
- #include "personlistbuddy.h"
- #include <QPainter>
- personListBuddy::personListBuddy(QWidget *parent) :
- QWidget(parent)
- {
- initUi();
- }
- //初始化Ui
- void personListBuddy::initUi()
- {
- //初始化
- head=new QWidget(this);
- name=new QLabel(this);
- sign=new QLabel(this);
- //設定頭像大小
- head->setFixedSize(40,40);
- //設定個性簽名字型為灰色
- QPalette color;
- color.setColor(QPalette::Text,Qt::gray);
- sign->setPalette(color);
- //布局
- head->move(7,7);
- name->move(54,10);
- sign->move(54,27);
- //裝載事件過濾器
- head->installEventFilter(this);
- }
- //事件過濾器,主要是為了讓圖檔能夠全部填充在head裡面
- bool personListBuddy::eventFilter(QObject *obj, QEvent *event)
- {
- if(obj == head)
- {
- if(event->type() == QEvent::Paint)
- {
- QPainter painter(head);
- painter.drawPixmap(head->rect(), QPixmap(headPath));
- }
- }
- return QWidget::eventFilter(obj, event);
- }
[cpp] view plain copy
- #include "personlistbuddy.h"
- #include <QPainter>
- personListBuddy::personListBuddy(QWidget *parent) :
- QWidget(parent)
- {
- initUi();
- }
- //初始化Ui
- void personListBuddy::initUi()
- {
- //初始化
- head=new QWidget(this);
- name=new QLabel(this);
- sign=new QLabel(this);
- //設定頭像大小
- head->setFixedSize(40,40);
- //設定個性簽名字型為灰色
- QPalette color;
- color.setColor(QPalette::Text,Qt::gray);
- sign->setPalette(color);
- //布局
- head->move(7,7);
- name->move(54,10);
- sign->move(54,27);
- //裝載事件過濾器
- head->installEventFilter(this);
- }
- //事件過濾器,主要是為了讓圖檔能夠全部填充在head裡面
- bool personListBuddy::eventFilter(QObject *obj, QEvent *event)
- {
- if(obj == head)
- {
- if(event->type() == QEvent::Paint)
- {
- QPainter painter(head);
- painter.drawPixmap(head->rect(), QPixmap(headPath));
- }
- }
- return QWidget::eventFilter(obj, event);
- }
二、實作好友清單personList類:
personList.h
[cpp] view plain copy
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5Gcu82Yp9VRE90Qvw1c0V2czF2LcRXZu5ibkN3YuUGZvN2Lc9CX6MHc0RHaiojIsJye.png)
- #ifndef PERSONLIST_H
- #define PERSONLIST_H
- #include <QListWidget>
- #include <QMenu>
- #include <QMouseEvent>
- #include <QLineEdit>
- //自定義QListWidget
- class personList : public QListWidget //繼承QListWidget,可以使用它本身自帶的函數,更友善
- {
- Q_OBJECT
- public:
- explicit personList(QListWidget *parent = 0);
- void mousePressEvent(QMouseEvent *event);//滑鼠點選事件
- void contextMenuEvent(QContextMenuEvent*);//菜單事件,為了顯示菜單
- void initMenu();//初始化菜單
- QMenu *blankMenu;//點選空白上的菜單
- QMenu *groupMenu;//點選組上的菜單
- QMenu *personMenu;//點選人上的菜單
- QMap<QListWidgetItem*,QListWidgetItem*> groupMap; // 組容器 - key:項 value:組
- QMap<QListWidgetItem*,bool> isHideMap;//用來判斷該組是否隐藏了
- QLineEdit *groupNameEdit;//組的名字,重命名的時候需要用到
- QListWidgetItem *currentItem;//目前的項
- signals:
- public slots:
- void slotAddGroup(); //添加組
- void slotDelGroup(); //删除組
- void slotAddBuddy(); //添加好友
- void slotDelBuddy(); //删除好友
- void slotRename(); //重命名組
- void slotRenameEditFshed();//命名完成
- };
- #endif // PERSONLIST_H
[cpp] view plain copy
- #ifndef PERSONLIST_H
- #define PERSONLIST_H
- #include <QListWidget>
- #include <QMenu>
- #include <QMouseEvent>
- #include <QLineEdit>
- //自定義QListWidget
- class personList : public QListWidget //繼承QListWidget,可以使用它本身自帶的函數,更友善
- {
- Q_OBJECT
- public:
- explicit personList(QListWidget *parent = 0);
- void mousePressEvent(QMouseEvent *event);//滑鼠點選事件
- void contextMenuEvent(QContextMenuEvent*);//菜單事件,為了顯示菜單
- void initMenu();//初始化菜單
- QMenu *blankMenu;//點選空白上的菜單
- QMenu *groupMenu;//點選組上的菜單
- QMenu *personMenu;//點選人上的菜單
- QMap<QListWidgetItem*,QListWidgetItem*> groupMap; // 組容器 - key:項 value:組
- QMap<QListWidgetItem*,bool> isHideMap;//用來判斷該組是否隐藏了
- QLineEdit *groupNameEdit;//組的名字,重命名的時候需要用到
- QListWidgetItem *currentItem;//目前的項
- signals:
- public slots:
- void slotAddGroup(); //添加組
- void slotDelGroup(); //删除組
- void slotAddBuddy(); //添加好友
- void slotDelBuddy(); //删除好友
- void slotRename(); //重命名組
- void slotRenameEditFshed();//命名完成
- };
- #endif // PERSONLIST_H
personList.cpp
[cpp] view plain copy
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5Gcu82Yp9VRE90Qvw1c0V2czF2LcRXZu5ibkN3YuUGZvN2Lc9CX6MHc0RHaiojIsJye.png)
- #include "personlist.h"
- #include <QAction>
- #include <QIcon>
- #include "personlistbuddy.h"
- personList::personList(QListWidget *parent) :
- QListWidget(parent)
- {
- setFocusPolicy(Qt::NoFocus); // 去除item選中時的虛線邊框
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//水準滾動條關閉
- initMenu();
- }
- //初始化菜單
- void personList::initMenu()
- {
- //初始化:
- blankMenu = new QMenu();
- groupMenu = new QMenu();
- personMenu = new QMenu();
- groupNameEdit=new QLineEdit();
- QAction *addGroup = new QAction("添加分組", this);
- QAction *delGroup = new QAction("删除該組", this);
- QAction *rename = new QAction("重命名", this);
- QAction *addBuddy = new QAction("添加好友",this);
- QAction *delBuddy = new QAction("删除好友", this);
- //設定:
- groupNameEdit->setParent(this); //設定父類
- groupNameEdit->hide(); //設定初始時隐藏
- groupNameEdit->setPlaceholderText("未命名");//設定初始時的内容
- //布局:
- blankMenu->addAction(addGroup);
- groupMenu->addAction(delGroup);
- groupMenu->addAction(rename);
- groupMenu->addAction(addBuddy);
- personMenu->addAction(delBuddy);
- //資訊槽:
- connect(groupNameEdit,SIGNAL(editingFinished()),this,SLOT(slotRenameEditFshed()));
- connect(addGroup,SIGNAL(triggered()),this,SLOT(slotAddGroup()));
- connect(delGroup,SIGNAL(triggered()),this,SLOT(slotDelGroup()));
- connect(rename,SIGNAL(triggered()),this,SLOT(slotRename()));
- connect(addBuddy,SIGNAL(triggered()),this,SLOT(slotAddBuddy()));
- connect(delBuddy,SIGNAL(triggered()),this,SLOT(slotDelBuddy()));
- }
- //滑鼠點選事件
- void personList::mousePressEvent(QMouseEvent *event)
- {
- QListWidget::mousePressEvent(event); // 如果不調用基類mousePressEvent,item被select會半天不響應,調用父類,讓QSS起效,因為QSS基于父類QListWidget,子類就是子視窗,就是最上層視窗,是覆寫在父視窗上的,是以先于父視窗捕獲消息
- //防止一種特殊情況:給新item命名、點選其他item或空白處時,指向新item的currentItem被賦予其他item
- if(groupNameEdit->isVisible() && !(groupNameEdit->rect().contains(event->pos())))
- {
- if(groupNameEdit->text()!=NULL)
- currentItem->setText(groupNameEdit->text());
- groupNameEdit->setText("");
- groupNameEdit->hide();
- }
- currentItem = this->itemAt(mapFromGlobal(QCursor::pos()));//滑鼠位置的Item,不管右鍵左鍵都擷取
- if(event->button()==Qt::LeftButton && currentItem!=NULL && currentItem==groupMap.value(currentItem))//如果點選的左鍵并且是點選的是組
- {
- if(isHideMap.value(currentItem)) //如果先前是隐藏,則顯示
- {
- foreach(QListWidgetItem* subItem, groupMap.keys(currentItem))//周遊組的對應的項(包括自身和好友)
- if(subItem!=currentItem) //如果是組的話不進行處理
- {
- subItem->setHidden(false); //好友全部顯示
- }
- isHideMap.insert(currentItem,false); //設定該組為顯示狀态
- currentItem->setIcon(QIcon(":/arrowDown"));
- }
- else //否則,先前是顯示,則隐藏
- {
- foreach(QListWidgetItem* subItem, groupMap.keys(currentItem))//周遊組的對應的項(包括自身和好友)
- if(subItem!=currentItem) //如果是組的話不進行處理
- {
- subItem->setHidden(true); //好友全部隐藏
- }
- isHideMap.insert(currentItem,true); //設定該組為隐藏狀态
- currentItem->setIcon(QIcon(":/arrowRight"));
- }
- }
- }
- //菜單事件,為了顯示菜單,點選滑鼠右鍵響應,滑鼠點選事件mousePressEvent優先于contextMenuEvent
- void personList::contextMenuEvent(QContextMenuEvent *event)
- {
- QListWidget::contextMenuEvent(event); //調用基類事件
- if(currentItem==NULL) //如果點選到的是空白處
- {
- blankMenu->exec(QCursor::pos());
- return;
- }
- if(currentItem==groupMap.value(currentItem)) // 如果點選到的是組
- groupMenu->exec(QCursor::pos());
- else //否則點選到的是好友
- personMenu->exec(QCursor::pos());
- }
- //添加組
- void personList::slotAddGroup()
- {
- QListWidgetItem *newItem=new QListWidgetItem(QIcon(":/arrowRight"),"未命名"); //建立一個Item
- newItem->setSizeHint(QSize(this->width(),25));//設定寬度、高度
- this->addItem(newItem); //加到QListWidget中
- groupMap.insert(newItem,newItem);//加到容器groupMap裡,key和value都為組
- isHideMap.insert(newItem,true); //設定該組隐藏狀态
- groupNameEdit->raise();
- groupNameEdit->setText(tr("未命名")); //設定預設内容
- groupNameEdit->selectAll(); //設定全選
- groupNameEdit->setGeometry(this->visualItemRect(newItem).left()+15,this->visualItemRect(newItem).top()+1,this->visualItemRect(newItem).width(),this->visualItemRect(newItem).height()-2);//出現的位置
- groupNameEdit->show(); //顯示
- groupNameEdit->setFocus(); //擷取焦點
- currentItem = newItem; // 因為要給group命名,是以目前的currentItem設為該group
- }
- //删除組
- void personList::slotDelGroup()
- {
- foreach(QListWidgetItem* item, groupMap.keys(currentItem)) //周遊該組的所有好友和自身的組
- {
- groupMap.remove(item); //移除
- delete item; //删除
- }
- isHideMap.remove(currentItem); //移除
- }
- //重命名
- void personList::slotRename()
- {
- groupNameEdit->raise();
- groupNameEdit->setGeometry(this->visualItemRect(currentItem).left()+15,this->visualItemRect(currentItem).top()+1,this->visualItemRect(currentItem).width(),this->visualItemRect(currentItem).height()-2);//出現的位置
- groupNameEdit->setText(currentItem->text()); //擷取該組名内容
- groupNameEdit->show(); //顯示
- groupNameEdit->selectAll(); //全選
- groupNameEdit->setFocus(); //擷取焦點
- }
- //添加好友,主要是為了測試功能,實際工程裡可以改成動态讀取資料庫進行添加好友
- void personList::slotAddBuddy()
- {
- personListBuddy *buddy=new personListBuddy(); //建立一個自己定義的資訊類
- buddy->headPath=":/head"; //設定頭像路徑
- buddy->name->setText("逍遙聖帝"); //設定使用者名
- buddy->sign->setText("用通俗的語言,講深刻的技術。"); //設定個性簽名
- QList<QListWidgetItem*> tem = groupMap.keys(currentItem);//目前組對應的項(包括組本身和好友)複制給tem
- //關鍵代碼
- QListWidgetItem *newItem = new QListWidgetItem(); //建立一個newItem
- this->insertItem(row(currentItem)+tem.count(),newItem); //将該newItem插入到後面
- this->setItemWidget(newItem, buddy); //将buddy賦給該newItem
- groupMap.insert(newItem,currentItem); //加進容器,key為好友,value為組
- if(isHideMap.value(currentItem)) //如果該組是隐藏,則加進去的好友設定為隐藏
- newItem->setHidden(true);
- else //否則,該好友設定為顯示
- newItem->setHidden(false);
- }
- //删除好友
- void personList::slotDelBuddy()
- {
- groupMap.remove(currentItem); //移除該好友
- delete currentItem; //删除
- }
- //重命名完成
- void personList::slotRenameEditFshed()
- {
- if(groupNameEdit->text()!=NULL) //如果重命名編輯框不為空
- currentItem->setText(groupNameEdit->text()); //更新組名
- groupNameEdit->setText("");
- groupNameEdit->hide(); //隐藏重命名編輯框
- }
[cpp] view plain copy
- #include "personlist.h"
- #include <QAction>
- #include <QIcon>
- #include "personlistbuddy.h"
- personList::personList(QListWidget *parent) :
- QListWidget(parent)
- {
- setFocusPolicy(Qt::NoFocus); // 去除item選中時的虛線邊框
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//水準滾動條關閉
- initMenu();
- }
- //初始化菜單
- void personList::initMenu()
- {
- //初始化:
- blankMenu = new QMenu();
- groupMenu = new QMenu();
- personMenu = new QMenu();
- groupNameEdit=new QLineEdit();
- QAction *addGroup = new QAction("添加分組", this);
- QAction *delGroup = new QAction("删除該組", this);
- QAction *rename = new QAction("重命名", this);
- QAction *addBuddy = new QAction("添加好友",this);
- QAction *delBuddy = new QAction("删除好友", this);
- //設定:
- groupNameEdit->setParent(this); //設定父類
- groupNameEdit->hide(); //設定初始時隐藏
- groupNameEdit->setPlaceholderText("未命名");//設定初始時的内容
- //布局:
- blankMenu->addAction(addGroup);
- groupMenu->addAction(delGroup);
- groupMenu->addAction(rename);
- groupMenu->addAction(addBuddy);
- personMenu->addAction(delBuddy);
- //資訊槽:
- connect(groupNameEdit,SIGNAL(editingFinished()),this,SLOT(slotRenameEditFshed()));
- connect(addGroup,SIGNAL(triggered()),this,SLOT(slotAddGroup()));
- connect(delGroup,SIGNAL(triggered()),this,SLOT(slotDelGroup()));
- connect(rename,SIGNAL(triggered()),this,SLOT(slotRename()));
- connect(addBuddy,SIGNAL(triggered()),this,SLOT(slotAddBuddy()));
- connect(delBuddy,SIGNAL(triggered()),this,SLOT(slotDelBuddy()));
- }
- //滑鼠點選事件
- void personList::mousePressEvent(QMouseEvent *event)
- {
- QListWidget::mousePressEvent(event); // 如果不調用基類mousePressEvent,item被select會半天不響應,調用父類,讓QSS起效,因為QSS基于父類QListWidget,子類就是子視窗,就是最上層視窗,是覆寫在父視窗上的,是以先于父視窗捕獲消息
- //防止一種特殊情況:給新item命名、點選其他item或空白處時,指向新item的currentItem被賦予其他item
- if(groupNameEdit->isVisible() && !(groupNameEdit->rect().contains(event->pos())))
- {
- if(groupNameEdit->text()!=NULL)
- currentItem->setText(groupNameEdit->text());
- groupNameEdit->setText("");
- groupNameEdit->hide();
- }
- currentItem = this->itemAt(mapFromGlobal(QCursor::pos()));//滑鼠位置的Item,不管右鍵左鍵都擷取
- if(event->button()==Qt::LeftButton && currentItem!=NULL && currentItem==groupMap.value(currentItem))//如果點選的左鍵并且是點選的是組
- {
- if(isHideMap.value(currentItem)) //如果先前是隐藏,則顯示
- {
- foreach(QListWidgetItem* subItem, groupMap.keys(currentItem))//周遊組的對應的項(包括自身和好友)
- if(subItem!=currentItem) //如果是組的話不進行處理
- {
- subItem->setHidden(false); //好友全部顯示
- }
- isHideMap.insert(currentItem,false); //設定該組為顯示狀态
- currentItem->setIcon(QIcon(":/arrowDown"));
- }
- else //否則,先前是顯示,則隐藏
- {
- foreach(QListWidgetItem* subItem, groupMap.keys(currentItem))//周遊組的對應的項(包括自身和好友)
- if(subItem!=currentItem) //如果是組的話不進行處理
- {
- subItem->setHidden(true); //好友全部隐藏
- }
- isHideMap.insert(currentItem,true); //設定該組為隐藏狀态
- currentItem->setIcon(QIcon(":/arrowRight"));
- }
- }
- }
- //菜單事件,為了顯示菜單,點選滑鼠右鍵響應,滑鼠點選事件mousePressEvent優先于contextMenuEvent
- void personList::contextMenuEvent(QContextMenuEvent *event)
- {
- QListWidget::contextMenuEvent(event); //調用基類事件
- if(currentItem==NULL) //如果點選到的是空白處
- {
- blankMenu->exec(QCursor::pos());
- return;
- }
- if(currentItem==groupMap.value(currentItem)) // 如果點選到的是組
- groupMenu->exec(QCursor::pos());
- else //否則點選到的是好友
- personMenu->exec(QCursor::pos());
- }
- //添加組
- void personList::slotAddGroup()
- {
- QListWidgetItem *newItem=new QListWidgetItem(QIcon(":/arrowRight"),"未命名"); //建立一個Item
- newItem->setSizeHint(QSize(this->width(),25));//設定寬度、高度
- this->addItem(newItem); //加到QListWidget中
- groupMap.insert(newItem,newItem);//加到容器groupMap裡,key和value都為組
- isHideMap.insert(newItem,true); //設定該組隐藏狀态
- groupNameEdit->raise();
- groupNameEdit->setText(tr("未命名")); //設定預設内容
- groupNameEdit->selectAll(); //設定全選
- groupNameEdit->setGeometry(this->visualItemRect(newItem).left()+15,this->visualItemRect(newItem).top()+1,this->visualItemRect(newItem).width(),this->visualItemRect(newItem).height()-2);//出現的位置
- groupNameEdit->show(); //顯示
- groupNameEdit->setFocus(); //擷取焦點
- currentItem = newItem; // 因為要給group命名,是以目前的currentItem設為該group
- }
- //删除組
- void personList::slotDelGroup()
- {
- foreach(QListWidgetItem* item, groupMap.keys(currentItem)) //周遊該組的所有好友和自身的組
- {
- groupMap.remove(item); //移除
- delete item; //删除
- }
- isHideMap.remove(currentItem); //移除
- }
- //重命名
- void personList::slotRename()
- {
- groupNameEdit->raise();
- groupNameEdit->setGeometry(this->visualItemRect(currentItem).left()+15,this->visualItemRect(currentItem).top()+1,this->visualItemRect(currentItem).width(),this->visualItemRect(currentItem).height()-2);//出現的位置
- groupNameEdit->setText(currentItem->text()); //擷取該組名内容
- groupNameEdit->show(); //顯示
- groupNameEdit->selectAll(); //全選
- groupNameEdit->setFocus(); //擷取焦點
- }
- //添加好友,主要是為了測試功能,實際工程裡可以改成動态讀取資料庫進行添加好友
- void personList::slotAddBuddy()
- {
- personListBuddy *buddy=new personListBuddy(); //建立一個自己定義的資訊類
- buddy->headPath=":/head"; //設定頭像路徑
- buddy->name->setText("逍遙聖帝"); //設定使用者名
- buddy->sign->setText("用通俗的語言,講深刻的技術。"); //設定個性簽名
- QList<QListWidgetItem*> tem = groupMap.keys(currentItem);//目前組對應的項(包括組本身和好友)複制給tem
- //關鍵代碼
- QListWidgetItem *newItem = new QListWidgetItem(); //建立一個newItem
- this->insertItem(row(currentItem)+tem.count(),newItem); //将該newItem插入到後面
- this->setItemWidget(newItem, buddy); //将buddy賦給該newItem
- groupMap.insert(newItem,currentItem); //加進容器,key為好友,value為組
- if(isHideMap.value(currentItem)) //如果該組是隐藏,則加進去的好友設定為隐藏
- newItem->setHidden(true);
- else //否則,該好友設定為顯示
- newItem->setHidden(false);
- }
- //删除好友
- void personList::slotDelBuddy()
- {
- groupMap.remove(currentItem); //移除該好友
- delete currentItem; //删除
- }
- //重命名完成
- void personList::slotRenameEditFshed()
- {
- if(groupNameEdit->text()!=NULL) //如果重命名編輯框不為空
- currentItem->setText(groupNameEdit->text()); //更新組名
- groupNameEdit->setText("");
- groupNameEdit->hide(); //隐藏重命名編輯框
- }
三、美化用到的QSS:
[cpp] view plain copy
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5Gcu82Yp9VRE90Qvw1c0V2czF2LcRXZu5ibkN3YuUGZvN2Lc9CX6MHc0RHaiojIsJye.png)
- QListWidget{
- background:white;
- color:black;
- border:none;
- }
- QListWidget::item{
- border:none;
- height: 54px;
- }
- QListWidget::item:hover{
- background:rgb(252,240,193)
- }
- QListWidget::item:selected{
- background:rgb(252,233,161);
- color:black;
- }
- QScrollBar:vertical {
- background:transparent;
- width:9px;
- margin: 0px 0px 2px 0px;
- }
- QScrollBar::handle:vertical {
- background: rgb(195, 195, 195);
- min-height: 20px;
- border-radius: 3px;
- }
- QScrollBar::handle:vertical:hover{
- background:rgba(0,0,0,30%);
- }
- QScrollBar::add-line:vertical {
- height: 0px;
- subcontrol-position: bottom;
- subcontrol-origin: margin;
- }
- QScrollBar::sub-line:vertical {
- height: 0px;
- subcontrol-position: top;
- subcontrol-origin: margin;
- }
[cpp] view plain copy
- QListWidget{
- background:white;
- color:black;
- border:none;
- }
- QListWidget::item{
- border:none;
- height: 54px;
- }
- QListWidget::item:hover{
- background:rgb(252,240,193)
- }
- QListWidget::item:selected{
- background:rgb(252,233,161);
- color:black;
- }
- QScrollBar:vertical {
- background:transparent;
- width:9px;
- margin: 0px 0px 2px 0px;
- }
- QScrollBar::handle:vertical {
- background: rgb(195, 195, 195);
- min-height: 20px;
- border-radius: 3px;
- }
- QScrollBar::handle:vertical:hover{
- background:rgba(0,0,0,30%);
- }
- QScrollBar::add-line:vertical {
- height: 0px;
- subcontrol-position: bottom;
- subcontrol-origin: margin;
- }
- QScrollBar::sub-line:vertical {
- height: 0px;
- subcontrol-position: top;
- subcontrol-origin: margin;
- }
四、用到的素材:
五、效果圖: