Qt实现模拟微信联系人列表

联系人列表主要由两部分组成,每个联系人的状态消息框和一个列表组成,因此,我们用QListWidget和自定义的item来实现这个列表。

1、自定义message item

如图:
在这里插入图片描述
一个item由头像、昵称、最近的一条消息、最近一条消息的时间和关闭按钮组成,因此我们首先用designer按照需要的东西选择合适的控件进行绘制界面。
界面绘制完成之后,就需要完成界面所需要的一些槽函数,在这边,我们应该有一个主题思想是需要确定的,就是每个item所需要的数据由自己管理,这样,在管理这些数据的时候就会比较方便, 会避免在外界管理所有item的数据而形成的比较庞大的数据结构。
实现槽函数的方式有很多,这儿我们采用自定义属性的方式来确定一些需要的数据。题外:Qt的每个原生控件都有一些被 Q_PROPERTY qproperty- 定义的原始属性,Q_PROPERTY是一个宏。

# define Q_PROPERTY(...) QT_ANNOTATE_CLASS(qt_property, __VA_ARGS__)

我们也使用这种方法来添加一些自定义item的属性。如下:

class MsgItem : public QWidget
{    Q_OBJECT
     Q_PROPERTY(QString msg READ msg WRITE setMsg DESIGNABLE true)
 public:
    explicit MsgItem(QWidget *parent = 0);
     ~MsgItem();  
 private:
 	Ui::MsgItem *ui;
 };

使用这种自定义属性的方式需要实现的公有方法的格式是比较固定的。如下:

QString msg() const;
void setMsg(const QString& msg);

按照上面的方式实现其余的方法。
实现的列表点击每个item的时候会有选中的效果,这种选中的效果有两种实现方式,一种是最正常的方式,也就是借用QListWidget的itemClicked(QListWidgetItem*)信号来按部就班的实现;另一种是通过集成QWidget的mouse事件来模拟选中的效果。这个例子中两种方式都有涉猎。最终的item类定义如下:

class MsgItem : public QWidget
{    Q_OBJECT
     //可按照下面的方法自己添加需要的功能
     Q_PROPERTY(QString msg READ msg WRITE setMsg DESIGNABLE true)
     Q_PROPERTY(QString header READ header WRITE setHeader DESIGNABLE true)
     Q_PROPERTY(QString name READ name WRITE setName DESIGNABLE true)
     Q_PROPERTY(QString uuid READ uuid WRITE setUuid DESIGNABLE true)
     Q_PROPERTY(QString datetime READ datetime WRITE setDatetime DESIGNABLE true)
     Q_PROPERTY(int count READ count WRITE setCount DESIGNABLE true)

public:
    explicit MsgItem(QWidget *parent = 0);
     ~MsgItem();

    QString msg() const;
    void setMsg(const QString& msg);

    QString header() const;
    void setHeader(const QString& header);

    QString uuid() const
    {
        return m_uuid;
    }
    void setUuid(const QString& uuid)
    {
        m_uuid = uuid;
    }

    QString name() const;
    void setName(const QString& name);

    QString datetime() const;
    void setDatetime(const QString& datetime);

    int count() const;
    void setCount(const int count);

    void setData( const QString &msg,
                        const QString& nick,
                        const QString& header,
                        const QString& name,
                        const QString& time );

    void selected(bool selected);

protected:
     virtual void mousePressEvent( QMouseEvent *event );


private slots:
     void on_btnDeleteClicked();

signals:
     void signal_selected(MsgItem*);
     void signal_delete(QWidget*);

private:
     Ui::MsgItem *ui;
     QString m_header{""};
     QString m_uuid{""};
};

其中的实现也比较简单,就是简单的设置一些界面的信息显示。我们看一下选中的效果实现:

void MsgItem::selected(bool selected)
{
    ui->widgetMain->setStyleSheet(selected ? 
    QString("QWidget#widgetMain{ background-color: #F2F2F2; border-bottom: 1px solid #F2F2F2;}")
  : QString("QWidget#widgetMain{ background-color: #FFFFFF; border-bottom: 1px solid #F2F2F2;}" ));
    ui->btnClose->setVisible(selected);
    setCount(0);
}

选中的效果是通过设置不同的qss来实现。

2、容器的实现

容器的实现基本上没什么比较注重的地方,使用QListWidget的原始功能就能够实现。为了方便设置选中的效果的切换,我们需要定义一个成员变量来记录当前的item,当进行切换时,先设置上一个为未选中,再设置下一个为选中即可。

因为item是自定义的,因此创建item的时候需要将自定义的item通过setItemWidget(QListWidgetItem*, QWidget*)方法加载到原始的item上。如下所示:

void ListTemplate::AddWidgetMsgItem()
{
    auto pMsgItem = new MsgItem();
    QListWidgetItem *item = new QListWidgetItem;
    item->setSizeHint( QSize(360, 70));
    pMsgItem->setCount(99);
    ui->listWidget->addItem(item);
    ui->listWidget->setItemWidget(item, pMsgItem);

    connect(pMsgItem, &MsgItem::signal_selected, this, &ListTemplate::slot_selected);
    connect(pMsgItem, &MsgItem::signal_delete, this, &ListTemplate::slot_delete);
}

这边将MsgItem的创建操作放在函数体内是为了方便测试,通过函数参数的方式传递进来在实际使用过程中会比较方便。

选中效果的实现也比较简单,下面我们主要用一种方式实现,另一种方式在源代码中有,后面有链接。

//第一种选中的实现方式
void ListTemplate::slot_selected(MsgItem *pWidget)
{
    if(Q_NULLPTR == pWidget)
    {
        return;
    }
    if(Q_NULLPTR != m_pCurrentItem)
    {
         m_pCurrentItem->selected(false);
    }
	//先设置当前的为不选中即false状态,然后将点击的设置为选中状态,当前指针指向点击的item
    pWidget->selected(true);
    m_pCurrentItem = pWidget;
}

tem的删除也是比较简单的,但是在删除的时候别忘了资源回收。

void ListTemplate::slot_delete(QWidget* pWidget)
{
    delete pWidget;
    pWidget = Q_NULLPTR;
    QListWidgetItem *pItem = ui->listWidget->takeItem(ui->listWidget->currentRow());
    m_pCurrentItem = Q_NULLPTR;
    m_pCurrent = Q_NULLPTR;
}

这边有一个注意的点,假设信号槽的连接中没有参数,我们需要手动来获取加载在QListWidgetItem上的MsgItem,需要注意的是应该先使用iremWidget()来获取,再使用takeItem卸载QListWidgetItem,否则会出现取不到QWidget的情况。具体可以参考:
Qt 中 QListWidget 获取itemWidget() 失败
看下最终效果:
在这里插入图片描述
源码地址:https://gitee.com/Gqian_com/customcomponent

展开阅读全文

Python数据分析与挖掘

01-08
92讲视频课+16大项目实战+源码+¥800元课程礼包+讲师社群1V1答疑+社群闭门分享会=99元   为什么学习数据分析?       人工智能、大数据时代有什么技能是可以运用在各种行业的?数据分析就是。       从海量数据中获得别人看不见的信息,创业者可以通过数据分析来优化产品,营销人员可以通过数据分析改进营销策略,产品经理可以通过数据分析洞察用户习惯,金融从业者可以通过数据分析规避投资风险,程序员可以通过数据分析进一步挖掘出数据价值,它和编程一样,本质上也是一个工具,通过数据来对现实事物进行分析和识别的能力。不管你从事什么行业,掌握了数据分析能力,往往在其岗位上更有竞争力。    本课程共包含五大模块: 一、先导篇: 通过分析数据分析师的一天,让学员了解全面了解成为一个数据分析师的所有必修功法,对数据分析师不在迷惑。   二、基础篇: 围绕Python基础语法介绍、数据预处理、数据可视化以及数据分析与挖掘......这些核心技能模块展开,帮助你快速而全面的掌握和了解成为一个数据分析师的所有必修功法。   三、数据采集篇: 通过网络爬虫实战解决数据分析的必经之路:数据从何来的问题,讲解常见的爬虫套路并利用三大实战帮助学员扎实数据采集能力,避免没有数据可分析的尴尬。   四、分析工具篇: 讲解数据分析避不开的科学计算库Numpy、数据分析工具Pandas及常见可视化工具Matplotlib。   五、算法篇: 算法是数据分析的精华,课程精选10大算法,包括分类、聚类、预测3大类型,每个算法都从原理和案例两个角度学习,让你不仅能用起来,了解原理,还能知道为什么这么做。
©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值