会话好友区设计与开发(一)
前言
上一集,我们已经完成了中间区域的大致设计,也使用了一些假数据进行测试,这一集我们将会开始开发相关内容替换里面的假数据,那么废话不多说,废话也说了那么多,我们就开始吧。
设计
我们的每一个好友会话都需要有一个好友的头像、好友的昵称、以及一句预览信息。
大致如下:
我们就需要编写一个Item来表示每一个好友会话。我们就肯定需要传入三个参数,好友头像、好友昵称和预览信息。
根据上面的布局,我们也会选择使用网格布局。
代码实现
那么我们直接就来看代码
SessionFriendItem::SessionFriendItem(QWidget *owner, const QIcon &avatar, const QString &name, const QString &text):owner(owner)
{this->setFixedHeight(70);this->setStyleSheet("QWidget { background-color: rgb(231,231,231); }");//创建网格布局管理器QGridLayout* layout = new QGridLayout();layout->setContentsMargins(0,0,0,0);layout->setSpacing(0);this->setLayout(layout);//创建头像QPushButton* avatarBtn = new QPushButton();avatarBtn->setFixedSize(50,50);avatarBtn->setIconSize(QSize(50,50));avatarBtn->setIcon(avatar);avatarBtn->setStyleSheet("QPushButton { border: none; }");avatarBtn->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);//固定尺寸大小//创建昵称QLabel* nameLabel = new QLabel();nameLabel->setText(name);nameLabel->setStyleSheet("QLabel { font-size:18px; font-weight: 600; }");nameLabel->setFixedHeight(35);nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);//创建消息预览QLabel* messageLabel = new QLabel();messageLabel->setText(text);messageLabel->setFixedHeight(35);messageLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);layout->addWidget(avatarBtn,0,0,2,2);layout->addWidget(nameLabel,0,2,1,1);layout->addWidget(messageLabel,1,2,1,1);}
是不是看上去也是十分的简单?
代码解释
QSizePolicy的使用
这里我们使用了QSizePolicy,他有两种尺寸设计,一种是Fixed,另一种是Expanding。
其中Fixed是固定尺寸、Expanding是尽可能填满尺寸。
owner指针
看完代码,可能有同学想问了,不是就三个参数就足够了吗?这个owner是什么东西?你小子是不是诓我们呢?
还真不是,这个owner还真十分重要。
想一想我们在实现滚动效果做了些什么?
没错,我们添加了一个container成员,我们的Item是添加到这个layout里面去的,并不是直接添加到Area里面去的。
如果我们直接添加到Area里面去,我们就不需要这个owner了,我们可以直接通过Item的parent的操作就可以访问到Area里面的相关方法。
有些同学可能看不懂我想说什么。那么我们举个例子。
SessionFriendArea
是显示好友列表的区域,而SessionFriendItem
是列表中每个好友的代表。每个SessionFriendItem
可以显示好友的头像、昵称和最后一条消息的预览。现在,我们希望在用户点击某个SessionFriendItem
时,能够触发SessionFriendArea
中的一个方法,比如打开与该好友的聊天窗口。
首先,我们定义 SessionFriendArea
类,它有一个方法 openChatWithFriend。
class SessionFriendArea : public QWidget {Q_OBJECTpublic:explicit SessionFriendArea(QWidget *parent = nullptr) : QWidget(parent) {// 初始化界面等}void openChatWithFriend(const QString &friendName) {// 打开与指定好友的聊天窗口qDebug() << "Opening chat with" << friendName;}// 其他成员和方法...
};
接下来,我们定义 SessionFriendItem
类,并在构造函数中使用 owner
参数。
class SessionFriendItem : public QWidget {Q_OBJECTpublic:explicit SessionFriendItem(SessionFriendArea *owner, const QIcon &avatar, const QString &name, const QString &text, QWidget *parent = nullptr): QWidget(parent), m_owner(owner) {// 初始化界面等// 头像按钮点击事件connect(avatarBtn, &QPushButton::clicked, [this, name]() {if (m_owner) {m_owner->openChatWithFriend(name);}});}private:SessionFriendArea *m_owner; // 指向 SessionFriendArea 的指针QPushButton *avatarBtn; // 头像按钮// 其他成员变量...
};
在这个例子中,SessionFriendItem
的构造函数接受一个 SessionFriendArea
类型的指针 owner
。这个指针被用来记录 SessionFriendArea
的实例,以便在 SessionFriendItem
中可以调用 SessionFriendArea
的方法。
当用户点击 SessionFriendItem
的头像按钮时,我们通过 connect
函数将点击事件与一个 lambda 表达式连接起来。在这个 lambda 表达式中,我们调用 m_owner->openChatWithFriend(name)
,这样就可以打开与该好友的聊天窗口了。
这样,即使 SessionFriendItem
的 parent
是 SessionFriendArea
中的 container
布局,我们仍然可以通过 owner
成员变量来访问和操作 SessionFriendArea
。这就是 owner
参数的作用和使用方式。
那么这一集我们先讲到这里。