精华内容
下载资源
问答
  • qt好友列表

    2019-07-05 13:32:29
    qt 实现类似好友列表控件。
  • QT 之QTreeWidget实现好友列表

    千次阅读 热门讨论 2016-12-19 22:10:51
    QT 之QTreeWidget实现好友列表QT 之QTreeWidget实现好友列表 插叙 效果图 UI设计 上代码 下代码 结尾 插叙 在上期Demo中,我们的界面似乎有些开始成型了,那么今天我们一起来看看QQ中的好友列表,我们利用QT又该...

    QT 之QTreeWidget实现好友列表

    插叙

    在上期Demo中,我们的界面似乎有些开始成型了,那么今天我们一起来看看QQ中的好友列表,我们利用QT又该如何实现呢?

    效果图

    QQ

    UI设计

    在这这前,我们需要先把我们的UI界面设计好,一个好友是一个Item,所以,首先我们需要先设计一个Item的Widget,在这里我命名为ContactItem
    这里写图片描述

    有了Item,擦入到我们主面板中QTreeWidget中
    QtreeWidget

    然后,有了UI界面,我们再来看看代码如何实现

    上代码

    void Demo::initContactTree()
    {
        ui.contactTreeWidget->clear();
        //展开和收缩时信号,以达到变更我三角图片;
        connect(ui.contactTreeWidget, SIGNAL(itemExpanded(QTreeWidgetItem *)), this, SLOT(onItemExpanded(QTreeWidgetItem *)));
        connect(ui.contactTreeWidget, SIGNAL(itemCollapsed(QTreeWidgetItem *)), this, SLOT(onItemCollapsed(QTreeWidgetItem *)));
        //分组节点
        QTreeWidgetItem *pRootFriendItem = new QTreeWidgetItem();
        //设置Data用于区分,Item是分组节点还是子节点,0代表分组节点,1代表子节点
        pRootFriendItem->setData(0, Qt::UserRole, 0);
        QLabel *pItemName = new QLabel(ui.contactTreeWidget);
        pItemName->setStyleSheet("border-image: url(:/Demo/Resources/common/arrow_up.png);border-width:0 0 0 20;");
        int nMyFriendNum = 6;
        QString qsGroupName = QString(tr("myfriends")).arg(0).arg(nMyFriendNum);
        pItemName->setText(qsGroupName);
        //擦入分组节点
        ui.contactTreeWidget->addTopLevelItem(pRootFriendItem);
        ui.contactTreeWidget->setItemWidget(pRootFriendItem, 0, pItemName);
    
        for (int nIndex = 0; nIndex < nMyFriendNum; ++nIndex)
        {
            //添加子节点
            addMyFriendInfo(pRootFriendItem);
        }
    }
    
    void Demo::initStrangerTree()
    {
        QTreeWidgetItem *pRootFriendItem = new QTreeWidgetItem();
        int nMyStrangerNum = 1;
        设置Data用于区分,Item是分组节点还是子节点,0代表分组节点,1代表子节点
        pRootFriendItem->setData(0, Qt::UserRole, 0);
        QLabel *pItemName = new QLabel(ui.contactTreeWidget);
        pItemName->setStyleSheet("border-image: url(:/Demo/Resources/common/arrow_up.png);border-width:0 0 0 20;");
        QString qsGroupName = QString(tr("strnggers")).arg(0).arg(nMyStrangerNum);
        pItemName->setText(qsGroupName);
    
        for (int nIndex = 0; nIndex < nMyStrangerNum; ++nIndex)
        {
            //添加子节点
            addMyFriendInfo(pRootFriendItem);
        }
    
        ui.contactTreeWidget->addTopLevelItem(pRootFriendItem);
        ui.contactTreeWidget->setItemWidget(pRootFriendItem, 0, pItemName);
    }
    
    void Demo::onItemExpanded(QTreeWidgetItem *pItem)
    {
        bool bIsChild = pItem->data(0, Qt::UserRole).toBool();
        if (!bIsChild)
        {
            QWidget *pWidget = ui.contactTreeWidget->itemWidget(pItem, 0);
            if (pWidget)
            {
                pWidget->setStyleSheet("border-image: url(:/Demo/Resources/common/arrow_down.png);border-width:0 0 0 20;");
            }
        }
    }
    
    void Demo::onItemCollapsed(QTreeWidgetItem *pItem)
    {
        bool bIsChild = pItem->data(0, Qt::UserRole).toBool();
        if (!bIsChild)
        {
            QWidget *pWidget = ui.contactTreeWidget->itemWidget(pItem, 0);
            if (pWidget)
            {
                pWidget->setStyleSheet("border-image: url(:/Demo/Resources/common/arrow_up.png);border-width:0 0 0 20;");
            }
        }
    }
    
    void Demo::addMyFriendInfo(QTreeWidgetItem* pRootGroupItem)
    {
        QTreeWidgetItem *pChild = new QTreeWidgetItem();
        //添加子节点
        pChild->setData(0, Qt::UserRole, 1);
        ContactItem* pContactItem = new ContactItem(ui.contactTreeWidget);
        pContactItem->setContactName(QString(tr("userName")));
        pContactItem->setContactIcon(USER_ICON);
        pRootGroupItem->addChild(pChild);
        ui.contactTreeWidget->setItemWidget(pChild, 0, pContactItem);
    }

    看完代码,相信大家,应该都知道了是如何实现的了,没明白的,我们一起再交流交流O(∩_∩)O。

    //QSS效果代码:
    QTreeView
    {
       border-style:none;   
    }
    
    QTreeView::item
    {
       height: 26;
       color:rgba(255, 255, 255, 0);    
    }
    
    QTreeView::item:selected:active
    {
        background-color: rgba(135, 206, 250, 153);
    }
    
    QTreeView::item:selected:!active, QTreeView::item:hover 
    {
        background-color: rgba(135, 206, 250, 50);
    }

    下代码

    QT 之QTreeWidget实现好友列表

    结尾

    只为记录,只为分享! 愿所写能对你有所帮助。Good Good Study, Day Day Up!

    展开全文
  • Qt实现好友列表

    千次阅读 2017-03-23 17:16:04
     一直都认为,用最通俗的语言,讲解最深刻的技术,是每一个技术交流者应该考虑的事情,今天朋友问我,好友列表该怎么实现。我想起之前上网查阅的时候,发现网上介绍这块的内容甚少,而且讲解的不够好,于是,本着...

    转载地址:  http://blog.csdn.net/u010519432/article/details/26988515

         一直都认为,用最通俗的语言,讲解最深刻的技术,是每一个技术交流者应该考虑的事情,今天朋友问我,好友列表该怎么实现。我想起之前上网查阅的时候,发现网上介绍这块的内容甚少,而且讲解的不够好,于是,本着互相交流的精神,在这里讲解一下我是怎么实现QQ好友列表的。

    1、Q:关于好友列表到底是QTreeWidget/QTreeView还是QListWidget/QListView的问题?

          A:相信大家初次一看,大部分都认为是QTreeWidget,其实是用QListWidget或者QListView均可简单实现,在数据多的时候,QListWidget性能会降低,不过,对于好友列表来说,QListWidget足以,并且更加简单。所以,我继承的是QListWidget来实现。

    2、Q:关于如何实现一个Item具有多种信息,包括头像、用户名、个性签名等?

          A:该Item其实是一个继承了QWidget的自定义buddy类,把你所想要的信息全部在该buddy类里面布局好,甚至可以加进按钮,自定义的好处就在于,你想到什么,就能干什么,然后在QListWiget里面里通过实现

    1. QListWidgetItem *newItem = new QListWidgetItem();       //创建一个newItem  
    2. this->insertItem(row(currentItem)+tem.count(),newItem); //将该newItem插入到后面  
    3. this->setItemWidget(newItem, buddy); //将buddy赋给该newItem  
    QListWidgetItem *newItem = new QListWidgetItem();       //创建一个newItem
    this->insertItem(row(currentItem)+tem.count(),newItem); //将该newItem插入到后面
    this->setItemWidget(newItem, buddy); //将buddy赋给该newItem

    即可。

    3、Q:关于如何实现好友的展开与隐藏?

          A:这部分里我设置了两个容器:

    1. QMap<QListWidgetItem*,QListWidgetItem*> groupMap;   // 组容器 - key:项 value:组  
    2. QMap<QListWidgetItem*,bool> isHideMap;//用来判断该组是否隐藏了  
     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

    1. #ifndef PERSONLISTBUDDY_H  
    2. #define PERSONLISTBUDDY_H  
    3. #include <QWidget>  
    4. #include <QLabel>  
    5. #include <QEvent>  
    6. //自定义信息Item类  
    7. class personListBuddy : public QWidget  
    8. {  
    9.     Q_OBJECT  
    10. public:  
    11.     explicit personListBuddy(QWidget *parent = 0);  
    12.     void initUi();//初始化Ui  
    13.     QWidget *head;  //头像  
    14.     QLabel *name;  //用户名  
    15.     QLabel *sign;  //个性签名  
    16.     QString headPath;//头像路径  
    17.     bool eventFilter(QObject *obj, QEvent *event);//事件过滤器  
    18.       
    19. signals:  
    20.       
    21. public slots:  
    22.       
    23. };  
    24. #endif // PERSONLISTBUDDY_H  
    #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

    1. #include "personlistbuddy.h"  
    2. #include <QPainter>  
    3. personListBuddy::personListBuddy(QWidget *parent) :  
    4.     QWidget(parent)  
    5. {  
    6.     initUi();  
    7. }  
    8. //初始化Ui  
    9. void personListBuddy::initUi()  
    10. {  
    11.     //初始化  
    12.     head=new QWidget(this);  
    13.     name=new QLabel(this);  
    14.     sign=new QLabel(this);  
    15.     //设置头像大小  
    16.     head->setFixedSize(40,40);  
    17.     //设置个性签名字体为灰色  
    18.     QPalette color;  
    19.     color.setColor(QPalette::Text,Qt::gray);  
    20.     sign->setPalette(color);  
    21.     //布局  
    22.     head->move(7,7);  
    23.     name->move(54,10);  
    24.     sign->move(54,27);  
    25.     //装载事件过滤器  
    26.     head->installEventFilter(this);  
    27. }  
    28. //事件过滤器,主要是为了让图片能够全部填充在head里面  
    29. bool personListBuddy::eventFilter(QObject *obj, QEvent *event)  
    30. {  
    31.     if(obj == head)  
    32.     {  
    33.         if(event->type() == QEvent::Paint)  
    34.         {  
    35.             QPainter painter(head);  
    36.             painter.drawPixmap(head->rect(), QPixmap(headPath));  
    37.         }  
    38.     }  
    39.     return QWidget::eventFilter(obj, event);  
    40. }  
    #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

    1. #ifndef PERSONLIST_H  
    2. #define PERSONLIST_H  
    3. #include <QListWidget>  
    4. #include <QMenu>  
    5. #include <QMouseEvent>  
    6. #include <QLineEdit>  
    7. //自定义QListWidget  
    8. class personList : public QListWidget //继承QListWidget,可以使用它本身自带的函数,更方便  
    9. {  
    10.     Q_OBJECT  
    11. public:  
    12.     explicit personList(QListWidget *parent = 0);  
    13.     void mousePressEvent(QMouseEvent *event);//鼠标点击事件  
    14.     void contextMenuEvent(QContextMenuEvent*);//菜单事件,为了显示菜单  
    15.     void initMenu();//初始化菜单  
    16.     QMenu *blankMenu;//点击空白上的菜单  
    17.     QMenu *groupMenu;//点击组上的菜单  
    18.     QMenu *personMenu;//点击人上的菜单  
    19.     QMap<QListWidgetItem*,QListWidgetItem*> groupMap;   // 组容器 - key:项 value:组  
    20.     QMap<QListWidgetItem*,bool> isHideMap;//用来判断该组是否隐藏了  
    21.     QLineEdit *groupNameEdit;//组的名字,重命名的时候需要用到  
    22.     QListWidgetItem *currentItem;//当前的项  
    23.       
    24. signals:  
    25.       
    26. public slots:  
    27.     void slotAddGroup();   //添加组  
    28.     void slotDelGroup();   //删除组  
    29.     void slotAddBuddy();   //添加好友  
    30.     void slotDelBuddy();   //删除好友  
    31.     void slotRename();     //重命名组  
    32.     void slotRenameEditFshed();//命名完成  
    33.       
    34. };  
    35. #endif // PERSONLIST_H  
    #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

    1. #include "personlist.h"  
    2. #include <QAction>  
    3. #include <QIcon>  
    4. #include "personlistbuddy.h"  
    5. personList::personList(QListWidget *parent) :  
    6.     QListWidget(parent)  
    7. {  
    8.     setFocusPolicy(Qt::NoFocus);       // 去除item选中时的虚线边框  
    9.     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//水平滚动条关闭  
    10.     initMenu();  
    11. }  
    12. //初始化菜单  
    13. void personList::initMenu()  
    14. {  
    15.     //初始化:  
    16.     blankMenu = new QMenu();  
    17.     groupMenu = new QMenu();  
    18.     personMenu = new QMenu();  
    19.     groupNameEdit=new QLineEdit();  
    20.     QAction *addGroup = new QAction("添加分组"this);  
    21.     QAction *delGroup = new QAction("删除该组"this);  
    22.     QAction *rename = new QAction("重命名"this);  
    23.     QAction *addBuddy = new QAction("添加好友",this);  
    24.     QAction *delBuddy = new QAction("删除好友"this);  
    25.     //设置:  
    26.     groupNameEdit->setParent(this);  //设置父类  
    27.     groupNameEdit->hide(); //设置初始时隐藏  
    28.     groupNameEdit->setPlaceholderText("未命名");//设置初始时的内容  
    29.     //布局:  
    30.     blankMenu->addAction(addGroup);  
    31.     groupMenu->addAction(delGroup);  
    32.     groupMenu->addAction(rename);  
    33.     groupMenu->addAction(addBuddy);  
    34.     personMenu->addAction(delBuddy);  
    35.     //信息槽:  
    36.     connect(groupNameEdit,SIGNAL(editingFinished()),this,SLOT(slotRenameEditFshed()));  
    37.     connect(addGroup,SIGNAL(triggered()),this,SLOT(slotAddGroup()));  
    38.     connect(delGroup,SIGNAL(triggered()),this,SLOT(slotDelGroup()));  
    39.     connect(rename,SIGNAL(triggered()),this,SLOT(slotRename()));  
    40.     connect(addBuddy,SIGNAL(triggered()),this,SLOT(slotAddBuddy()));  
    41.     connect(delBuddy,SIGNAL(triggered()),this,SLOT(slotDelBuddy()));  
    42. }  
    43. //鼠标点击事件  
    44. void personList::mousePressEvent(QMouseEvent *event)  
    45. {  
    46.     QListWidget::mousePressEvent(event); // 如果不调用基类mousePressEvent,item被select会半天不响应,调用父类,让QSS起效,因为QSS基于父类QListWidget,子类就是子窗口,就是最上层窗口,是覆盖在父窗口上的,所以先于父窗口捕获消息  
    47.     //防止一种特殊情况:给新item命名、点击其他item或空白处时,指向新item的currentItem被赋予其他item  
    48.     if(groupNameEdit->isVisible() && !(groupNameEdit->rect().contains(event->pos())))  
    49.     {  
    50.         if(groupNameEdit->text()!=NULL)  
    51.             currentItem->setText(groupNameEdit->text());  
    52.         groupNameEdit->setText("");  
    53.         groupNameEdit->hide();  
    54.     }  
    55.     currentItem = this->itemAt(mapFromGlobal(QCursor::pos()));//鼠标位置的Item,不管右键左键都获取  
    56.     if(event->button()==Qt::LeftButton && currentItem!=NULL && currentItem==groupMap.value(currentItem))//如果点击的左键并且是点击的是组  
    57.     {  
    58.         if(isHideMap.value(currentItem))                                  //如果先前是隐藏,则显示  
    59.         {  
    60.             foreach(QListWidgetItem* subItem, groupMap.keys(currentItem))//遍历组的对应的项(包括自身和好友)  
    61.                 if(subItem!=currentItem)                                 //如果是组的话不进行处理  
    62.                 {  
    63.                     subItem->setHidden(false);                            //好友全部显示  
    64.                 }  
    65.             isHideMap.insert(currentItem,false);                          //设置该组为显示状态  
    66.             currentItem->setIcon(QIcon(":/arrowDown"));  
    67.         }  
    68.         else                                                             //否则,先前是显示,则隐藏  
    69.         {  
    70.             foreach(QListWidgetItem* subItem, groupMap.keys(currentItem))//遍历组的对应的项(包括自身和好友)  
    71.                 if(subItem!=currentItem)                                 //如果是组的话不进行处理  
    72.                 {  
    73.                     subItem->setHidden(true);                            //好友全部隐藏  
    74.                 }  
    75.              isHideMap.insert(currentItem,true);                          //设置该组为隐藏状态  
    76.              currentItem->setIcon(QIcon(":/arrowRight"));  
    77.         }  
    78.     }  
    79. }  
    80. //菜单事件,为了显示菜单,点击鼠标右键响应,鼠标点击事件mousePressEvent优先于contextMenuEvent  
    81. void personList::contextMenuEvent(QContextMenuEvent *event)  
    82. {  
    83.     QListWidget::contextMenuEvent(event);           //调用基类事件  
    84.     if(currentItem==NULL)                           //如果点击到的是空白处  
    85.     {  
    86.         blankMenu->exec(QCursor::pos());  
    87.         return;  
    88.     }  
    89.     if(currentItem==groupMap.value(currentItem))    // 如果点击到的是组  
    90.         groupMenu->exec(QCursor::pos());  
    91.     else                                            //否则点击到的是好友  
    92.         personMenu->exec(QCursor::pos());  
    93. }  
    94. //添加组  
    95. void personList::slotAddGroup()  
    96. {  
    97.     QListWidgetItem *newItem=new QListWidgetItem(QIcon(":/arrowRight"),"未命名");    //创建一个Item  
    98.     newItem->setSizeHint(QSize(this->width(),25));//设置宽度、高度  
    99.     this->addItem(newItem);         //加到QListWidget中  
    100.     groupMap.insert(newItem,newItem);//加到容器groupMap里,key和value都为组  
    101.     isHideMap.insert(newItem,true);  //设置该组隐藏状态  
    102.     groupNameEdit->raise();  
    103.     groupNameEdit->setText(tr("未命名")); //设置默认内容  
    104.     groupNameEdit->selectAll();        //设置全选  
    105.     groupNameEdit->setGeometry(this->visualItemRect(newItem).left()+15,this->visualItemRect(newItem).top()+1,this->visualItemRect(newItem).width(),this->visualItemRect(newItem).height()-2);//出现的位置  
    106.     groupNameEdit->show();              //显示  
    107.     groupNameEdit->setFocus();          //获取焦点  
    108.     currentItem = newItem;     // 因为要给group命名,所以当前的currentItem设为该group  
    109. }  
    110. //删除组  
    111. void personList::slotDelGroup()  
    112. {  
    113.     foreach(QListWidgetItem* item, groupMap.keys(currentItem))  //遍历该组的所有好友和自身的组  
    114.     {  
    115.         groupMap.remove(item);   //移除  
    116.         delete item;   //删除  
    117.     }  
    118.     isHideMap.remove(currentItem); //移除  
    119. }  
    120. //重命名  
    121. void personList::slotRename()  
    122. {  
    123.     groupNameEdit->raise();  
    124.     groupNameEdit->setGeometry(this->visualItemRect(currentItem).left()+15,this->visualItemRect(currentItem).top()+1,this->visualItemRect(currentItem).width(),this->visualItemRect(currentItem).height()-2);//出现的位置  
    125.     groupNameEdit->setText(currentItem->text());   //获取该组名内容  
    126.     groupNameEdit->show();                        //显示  
    127.     groupNameEdit->selectAll();                   //全选  
    128.     groupNameEdit->setFocus();                        //获取焦点  
    129. }  
    130. //添加好友,主要是为了测试功能,实际工程里可以改成动态读取数据库进行添加好友  
    131. void personList::slotAddBuddy()  
    132. {  
    133.     personListBuddy *buddy=new personListBuddy();   //创建一个自己定义的信息类  
    134.     buddy->headPath=":/head";                          //设置头像路径  
    135.     buddy->name->setText("逍遥圣帝");                  //设置用户名  
    136.     buddy->sign->setText("用通俗的语言,讲深刻的技术。");   //设置个性签名  
    137.     QList<QListWidgetItem*> tem = groupMap.keys(currentItem);//当前组对应的项(包括组本身和好友)复制给tem  
    138.     //关键代码  
    139.     QListWidgetItem *newItem = new QListWidgetItem();       //创建一个newItem  
    140.     this->insertItem(row(currentItem)+tem.count(),newItem); //将该newItem插入到后面  
    141.     this->setItemWidget(newItem, buddy); //将buddy赋给该newItem  
    142.     groupMap.insert(newItem,currentItem);   //加进容器,key为好友,value为组  
    143.     if(isHideMap.value(currentItem))          //如果该组是隐藏,则加进去的好友设置为隐藏  
    144.         newItem->setHidden(true);  
    145.     else                                      //否则,该好友设置为显示  
    146.         newItem->setHidden(false);  
    147. }  
    148. //删除好友  
    149. void personList::slotDelBuddy()  
    150. {  
    151.     groupMap.remove(currentItem);  //移除该好友  
    152.     delete currentItem;            //删除  
    153. }  
    154. //重命名完成  
    155. void personList::slotRenameEditFshed()  
    156. {  
    157.     if(groupNameEdit->text()!=NULL)      //如果重命名编辑框不为空  
    158.         currentItem->setText(groupNameEdit->text());  //更新组名  
    159.     groupNameEdit->setText("");  
    160.     groupNameEdit->hide();  //隐藏重命名编辑框  
    161. }  
    #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:

    1. QListWidget{  
    2.     background:white;  
    3.     color:black;  
    4.     border:none;  
    5. }  
    6.   
    7. QListWidget::item{  
    8.     border:none;  
    9.         height: 54px;  
    10. }  
    11.   
    12. QListWidget::item:hover{  
    13.     background:rgb(252,240,193)  
    14. }  
    15.   
    16. QListWidget::item:selected{  
    17.     background:rgb(252,233,161);  
    18.     color:black;  
    19. }  
    20.   
    21. QScrollBar:vertical {                 
    22.     background:transparent;  
    23.     width:9px;  
    24.     margin: 0px 0px 2px 0px;  
    25. }  
    26.   
    27. QScrollBar::handle:vertical {  
    28.     background: rgb(195, 195, 195);  
    29.     min-height: 20px;  
    30.     border-radius: 3px;  
    31. }  
    32.   
    33. QScrollBar::handle:vertical:hover{  
    34.     background:rgba(0,0,0,30%);  
    35. }  
    36.   
    37. QScrollBar::add-line:vertical {  
    38.     height: 0px;  
    39.     subcontrol-position: bottom;  
    40.     subcontrol-origin: margin;  
    41. }  
    42.   
    43. QScrollBar::sub-line:vertical {  
    44.     height: 0px;  
    45.     subcontrol-position: top;  
    46.     subcontrol-origin: margin;  
    47. }  
    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;
    }

    四、用到的素材:



    五、效果图:


    展开全文
  • Qt实现类似QQ好友列表

    千次阅读 2016-07-24 15:41:13
    思路做个类似QQ好友列表的控件。 网上查询到的思路: 利用一组一组的QToolButton的来实现。 采用QLisview和QTreeView实现。通过代理来设置每一个项的样子。 采用QListWidget,然后通过setItemWidget来实现。 考虑后...

    思路

    做个类似QQ好友列表的控件。
    网上查询到的思路:

    1. 利用一组一组的QToolButton的来实现

    2. 采用QLisview和QTreeView实现。通过代理来设置每一个项的样子。

    3. 采用QListWidget,然后通过setItemWidget来实现。

    考虑后才用第二种方式,第一种方式实现起来样式不好设置,第三种widget太多,对系统资源占用比较大。每一个组用一个QToolButton和一个QListView来表示,QListView用delegate来设置样子。列表的展开和收缩,通过QListView的hide函数来实现。

    实现

    listView

    关于Model View delegate自定义列表的文章可以参考:如何使用Model View delegate自定义列表

    一个只读的delegate

    只需要实现继承QStyledItemDelegate的GroupListViewDelegate其中的paint和sizeHint就可以了。paint用来绘制item的样子,sizeHint用来设置行高。

    void GroupListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        const QPixmap &pixmap = qvariant_cast<QPixmap>(index.data(Qt::UserRole + 1));
        QRect pixmapRect = QRect(option.rect.topLeft(), QSize(50, 50));
    
        const QString &str = index.data(Qt::UserRole).toString();
        QFontMetrics font(painter->fontMetrics());
        QRect diplayRect = QRect(pixmapRect.topRight() + QPoint(20, 25), QSize(font.width(str), font.height()));
        painter->drawPixmap(pixmapRect, pixmap);
        painter->drawText(diplayRect, str);
    }
    
    QSize GroupListViewDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const
    {
        return QSize(option.rect.width(), 50);
    }

    更新后台数据的model

    继承QAbstractListModel的GroupListViewModel中,我们实现一个rowCount的函数来返回Item的列数,实现一个data的函数来给listview或delegate来提供各种图片或数据。

    int GroupListViewModel::rowCount(const QModelIndex &/*parent*/) const
    {
        return m_patients.count();
    }  
    
    QVariant GroupListViewModel::data(const QModelIndex &index, int role) const
    {
        if(!index.isValid() || (index.row() > m_patients.count())) {
            return QVariant();
        }
    
        if(role == Qt::UserRole) {
            return m_patients.at(index.row()).name();
        } if(role == Qt::UserRole + 1) {
            QString localPath = ":/mainface/default_head";
            QString id = m_patients.at(index.row()).id();
    
            if(m_pixmapMap.contains(id)) {
                localPath = m_pixmapMap.value(id);
            }
    
            QPixmap pixmap;
            pixmap.load(localPath);
            return pixmap.scaled(QSize(50, 50), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
        } else if(role == Qt::UserRole + 2) {
            return m_patients.at(index.row()).id();
        }
    
        return QVariant();
    }

    model中用一个QList m_patients来保存主要的信息。通过对List的数据的操作来更新model的数据。

    到此,ListView后面只需要实现一个删除联系人和移动联系人的事件。listView的大部分功能就实现。对于每组点击栏,我们可以用一个QToolButton来放箭头图片,用一个QPushButton来存放组名字,绑定二者的点击事件,并且通过点击事件后来设置图片切换箭头的样子,并发出信号控制ListView的隐藏或者显示。

    代码实现:http://download.csdn.net/detail/lwei3600103/9584766

    参考资料

    1,http://blog.sina.com.cn/s/blog_a6fb6cc90102v7qb.html
    2,http://blog.csdn.net/feiyangyangfei/article/details/8504043

    展开全文
  • qt,qq好友列表

    2018-07-16 17:22:34
    qt实现的qq好友列表,抽屉列表,可自定义列表的子窗口的布局
  • 实现的效果对标QQ的好友列表。 用工具盒类(QToolBox)实现,提供一种列状的层叠窗口,而QToolButton提供一种快速访问命令或者选择项的按钮。 抽屉效果是软件界面设计中的一种常用形式
  • QT实现类似QQ好友分组列表源代码,可以自定义分组,可以自定义添加删除好友,添加删除分组..........................................................................................................................
  • Qt 实现QQ好友列表

    2016-11-25 09:08:38
    我想通过QTreeView 实现QQ列表,我自己定义了一个有几个控件的widget ,怎么通过委托把这个widget绘制到item上面
  • 利用qt实现局域网聊天功能、文件传送功能,并自定义好友列表
  • Qt实现QQ好友下拉列表

    千次阅读 2013-08-24 20:31:12
    偶然发现Qt有个控件可以实现下拉列表,所以就试着实现一下类似QQ面板的下拉列表,这里主要实现几个功能:  1.可以删除列表中图标  2.可以像qq一样的,把某个分组下的图标转移到另外的分组  3.添加分组 代码里...

        偶然发现Qt有个控件可以实现下拉列表,所以就试着实现一下类似QQ面板的下拉列表,这里主要实现几个功能:

       1.可以删除列表中图标

       2.可以像qq一样的,把某个分组下的图标转移到另外的分组

      3.添加分组

    代码里写了注释了,这里就不重复了,下面直接看代码吧。

    自定义的数据模型

    ListModel继承了QAbstractListModel,主要是实现要显示的数据结构。用的是model/view的三层结构,这样好拆分

    
    struct ListItemData
    {
    	QString  iconPath;
    	QString  Name;
    
    };
    
    class ListModel:public QAbstractListModel
    {
    	Q_OBJECT
    public:
    	ListModel(QObject *parent = NULL);
    	~ListModel();
    
    	void init();
    	void addItem(ListItemData *pItem);
    	QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const ;
    	int	rowCount ( const QModelIndex & parent = QModelIndex() ) const;
    	void deleteItem(int index);
    	ListItemData* getItem(int index );
    protected:
    private:
    	vector<ListItemData*> m_ItemDataVec;
    };
    ListModel::ListModel( QObject *parent /*= NULL*/ ):QAbstractListModel(parent)
    {
    	init();
    }
    
    ListModel::~ListModel()
    {
    
    }
    
    QVariant ListModel::data( const QModelIndex & index, int role /*= Qt::DisplayRole */ ) const
    {
    	if (index.row() > m_ItemDataVec.size())
    	{
    		return QVariant();
    	} 
    	else
    	{
    	   switch (role)
    	   {
    	   case Qt::DisplayRole:
    		   {
    			   return m_ItemDataVec[index.row()]->Name;
    		   }
    	   	break;
    	   case Qt::DecorationRole:
    		   {
    			   return QIcon(m_ItemDataVec[index.row()]->iconPath);
    		   }
    		   break;
    	 case Qt::SizeHintRole:
    		   {
    			   return QSize(10,50);
    
    		   }
    	   }
    	}
    	return QVariant();
    }
    
    
    
    int ListModel::rowCount( const QModelIndex & parent /*= QModelIndex() */ ) const
    {
    	return m_ItemDataVec.size();
    }
    
    void ListModel::init()
    {
    	for (int i = 1; i < 26; ++i)
    	{ 
    		ListItemData *pItem = new ListItemData;
    		pItem->Name = QString::number(i);
    		pItem->iconPath = QString(":/QQPanel/Resources/%1.jpg").arg(i);
    		QFile Iconfile(pItem->iconPath);
    		if (Iconfile.exists())
    		{
    			m_ItemDataVec.push_back(pItem);
    		}
    		
    	}
    }
    
    void ListModel::deleteItem( int index )
    {
    	vector<ListItemData*>::iterator it = m_ItemDataVec.begin();
    	m_ItemDataVec.erase(it + index);
    }
    
    void ListModel::addItem( ListItemData *pItem )
    {
    	if (pItem)
    	{
    		this->beginInsertRows(QModelIndex(),m_ItemDataVec.size(),m_ItemDataVec.size() + 1);
    		m_ItemDataVec.push_back(pItem);
    		this->endInsertRows();
    	}
    	
    }
    
    ListItemData* ListModel::getItem( int index )
    {
    	if (index > -1 && index < m_ItemDataVec.size())
    	{
    		return m_ItemDataVec[index];
    	}
    }
    


    
    


    自定义的列表

    这个类才是重点,因为这里实现了删除和转移图标的几个重要的函数。
    class MyListView:public QListView
    {
    	Q_OBJECT
    public:
    	MyListView(QWidget *parent = NULL);
    	~MyListView();
    	void setListMap(map<MyListView*,QString> *pListMap);
    	void addItem(ListItemData *pItem);
    protected:
    	void contextMenuEvent ( QContextMenuEvent * event );
    private slots:
    	void deleteItemSlot(bool bDelete);
    	void moveSlot(bool bMove);
    private:
    	int  m_hitIndex;
    	ListModel   *m_pModel;
    	记录分组和分组名字的映射关系,这个值跟QQPanel类中的映射组的值保持一致 
    	//这里还有一个用处就是在弹出的菜单需要分组的名称
    	map<MyListView*,QString> *m_pListMap;   
    	//记录每个菜单项对应的列表,才能知道要转移到那个分组
    	map<QAction*,MyListView*> m_ActionMap;   
    };

    
    MyListView::MyListView( QWidget *parent /*= NULL*/ ):QListView(parent)
    {
    	m_hitIndex = -1;
    	m_pModel = new ListModel;
    	this->setModel(m_pModel);
    	m_pListMap = NULL;
    }
    
    MyListView::~MyListView()
    {
    
    }
    
    void MyListView::contextMenuEvent( QContextMenuEvent * event )
    {
    	int hitIndex = this->indexAt(event->pos()).column();
    	if (hitIndex > -1)
    	{
    		QMenu *pMenu = new QMenu(this);
    		QAction *pDeleteAct = new QAction(tr("删除"),pMenu);
    		pMenu->addAction(pDeleteAct);
    		connect(pDeleteAct,SIGNAL(triggered (bool)),this,SLOT(deleteItemSlot(bool)));
    		QMenu *pSubMenu = NULL;
    		map<MyListView*,QString>::iterator it = m_pListMap->begin();
    		for (it;it != m_pListMap->end();++it)
    		{
    			if (!pSubMenu)
    			{
    				pSubMenu = new QMenu(tr("转移联系人至") ,pMenu);
    				pMenu->addMenu(pSubMenu);
    			}
    			if (it->first != this)
    			{
    				QAction *pMoveAct = new QAction( it->second ,pMenu);
    				//记录菜单与分组的映射,在moveSlot()响应时需要用到。
    				m_ActionMap.insert(pair<QAction*,MyListView*>(pMoveAct,it->first));
    				pSubMenu->addAction(pMoveAct);
    				connect(pMoveAct,SIGNAL(triggered (bool)),this,SLOT(moveSlot(bool)));
    			}
    			
    		}
    
    		pMenu->popup(mapToGlobal(event->pos()));
    	}
    }
    
    void MyListView::deleteItemSlot( bool bDelete )
    {
    	int index = this->currentIndex().row();
    	if (index > -1)
    	{
    		m_pModel->deleteItem(index);
    	}
    }
    
    void MyListView::setListMap( map<MyListView*,QString> *pListMap )
    {
    	m_pListMap = pListMap;
    }
    
    void MyListView::addItem( ListItemData *pItem )
    {
    	m_pModel->addItem(pItem);
    }
    
    void MyListView::moveSlot( bool bMove )
    {
    	QAction *pSender = qobject_cast<QAction*>(sender());
    	if (pSender)
    	{
    		//根据点击的菜单,找到相应的列表,然后才能把图标转移过去
    		MyListView *pList = m_ActionMap.find(pSender)->second;
    		if (pList)
    		{
    			int index = this->currentIndex().row();
    			ListItemData *pItem = m_pModel->getItem(index);
    			pList->addItem(pItem);
    			//添加到别的分组,就在原来的分组中删除掉了
    			m_pModel->deleteItem(index);
    		}
    	}
    	//操作完了要把这个临时的映射清空
    	m_ActionMap.clear();
    }
    

    自定义的主控件

    class QQPanel : public QWidget
    {
    	Q_OBJECT
    	
    public:
    	QQPanel(QWidget *parent = 0, Qt::WFlags flags = 0);
    	~QQPanel();
    
    protected:
    	void contextMenuEvent ( QContextMenuEvent * event );
    
    protected slots:
    	void addGroupSlot(bool addgroup);
    private:
    	QToolBox    *m_pBox;
    	map<MyListView*,QString> *m_pListMap;    //记录分组和分组名字的映射关系,好在转移图标时知道转移到那个分组
    
    };

    QQPanel::QQPanel(QWidget *parent, Qt::WFlags flags)
    	: QWidget(parent, flags)
    {
    	m_pBox = new QToolBox(this);
    	m_pListMap = new map<MyListView*,QString>();
    	MyListView *pListView = new MyListView(this);
    	pListView->setViewMode(QListView::ListMode);
    	pListView->setStyleSheet("QListView{icon-size:40px}");
    	m_pBox->addItem(pListView,tr("我的好友"));
    	m_pListMap->insert(pair<MyListView*,QString>(pListView,tr("我的好友")));
    
    	MyListView *pListView1 = new MyListView(this);
    	pListView1->setViewMode(QListView::ListMode);
    	pListView1->setStyleSheet("QListView{icon-size:40px}");
    	m_pBox->addItem(pListView1,tr("陌生人"));
    	m_pListMap->insert(pair<MyListView*,QString>(pListView1,tr("陌生人")));
    
    	pListView->setListMap(m_pListMap);
    	pListView1->setListMap(m_pListMap);
    	m_pBox->setFixedWidth(150);
    	m_pBox->setMinimumHeight(500);
    	this->setMinimumSize(200,500);
    	//ui.setupUi(this);
    }
    
    QQPanel::~QQPanel()
    {
    
    }
    
    void QQPanel::contextMenuEvent( QContextMenuEvent * event )
    {
    	QMenu *pMenu = new QMenu(this);
    	QAction *pAddGroupAct = new QAction(tr("添加分组"),pMenu);
    	pMenu->addAction(pAddGroupAct);
    	connect(pAddGroupAct,SIGNAL(triggered (bool)),this,SLOT(addGroupSlot(bool)));
    	pMenu->popup(mapToGlobal(event->pos()));
    }
    
    
    void QQPanel::addGroupSlot( bool addgroup )
    {
        QString name = QInputDialog::getText(this,tr("输入分组名"),tr(""));
    	if (!name.isEmpty())
    	{
    		MyListView *pListView1 = new MyListView(this);
    		pListView1->setViewMode(QListView::ListMode);
    		pListView1->setStyleSheet("QListView{icon-size:40px}");
    		m_pBox->addItem(pListView1,name);
    		m_pListMap->insert(pair<MyListView*,QString>(pListView1,name));
    	}
    	//要确保每个MyListView钟的m_pListMap都是一致的,不然就会有错了。
    	//因为弹出的菜单进行转移的时候需要用到
    	map<MyListView*,QString>::iterator it = m_pListMap->begin();
    	for (it; it != m_pListMap->end(); ++it)
    	{
    		MyListView* pList = it->first;
    		pList->setListMap(m_pListMap);
    	}
    }
    

    运行结果



    由以上两个截图显示,我的好友和陌生人的个有5个图标




    以上两个截图显示,把陌生人中图标5转移到我的好友里



    以上两个截图,显示添加了一个分组,黑名单,因为我默认列表在创建时都有相同的5个图标



      以上三个截图显示了把黑名单里的图标5转移到了我的好友分组里了

    当然这个程序算是比较简单的。还不能真正的跟QQ的面板相比,还不能把所有的分组都收起来。以后再慢慢研究怎么实现了,



    展开全文
  • 为了创建人物信息,我们定义了一个initWidget()函数,主要实现是创建了三个标签,分别用来显示图像、名字、个人说明。 创建完人物之后,再将他们添加至QGroupBox分组中。最后,通过addItem()添加所有的分组。这样...
  • 不仅可以实现类似QQ好友列表的抽屉效果,还能支持很多额外的拓展,。但是是为读者提供一个思路,读者可以自由扩展,封装成自己的类,供自己使用。 如果只要显示抽屉效果,IMToolItem这个类已经完全够用。
  • 对按钮显示信息进行设置,令每个按钮表示一个好友,创建类FriList使共有其继承于QToolBox,保留QToolBox的成员函数,好友添加、群组添加等函数。将设置好的按钮添加进页面中。最后利用QVBoxLayout的...
  • Xfriends是X11 / Qt好友列表程序。 它使用手指操作,因此您的好友不必运行Xfriends。
  • 基于Qt的仿QQ好友列表面板
  • 大家看看YY的好友列表,咋一看像是QT的树控件实现的,其实我估摸着95%应该是用QListView实现的,但是这不想到了这一步,却遇到了一些疑惑,所以想跟大家交流一下。 如果是用QListView实现的话,那么就有父节点、...
  • QT实现的聊天界面,好友列表,支持文字和动态图像收发,python写的,C语言也可以参考
  • QT QListView写的仿微信好友列表,列表仿微信好友列表(头像+上下双行数据),还有单击获取信息的功能;效果图在 https://blog.csdn.net/u014385680/article/details/104963956
  • 这段代码不仅能够实现QQ好友列表的抽屉效果,还能支持非常多额外的拓展。。 可是是为读者提供一个思路,读者能够自由扩展,封装成自己的类,供自己使用。 假设仅仅要显示抽屉效果。IMToolItem这个类已经全然够用。...
  • 如题 我想用一个label显示消息的数量 就是类似于QQ那种未读消息红点显示的那种 item所在的treewidget->setItemwidget()添加一个列为label 可是运行起来却不显示这个label 求教
  • 本文主要总结用Qt的自定义按钮和QWidget界面实现QQ好友列表的界面伸展和收缩功能,以及鼠标滑过、鼠标单击的QSS样式表效果。全文分为两大部分,分别是原理讲解和效果实现。 抽缩界面效果图 源代码下载地址:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,189
精华内容 475
关键字:

qt好友列表实现