会话好友区设计与开发(一)
前言
上一集,我们已经完成了中间区域的大致设计,也使用了一些假数据进行测试,这一集我们将会开始开发相关内容替换里面的假数据,那么废话不多说,废话也说了那么多,我们就开始吧。
设计
我们的每一个好友会话都需要有一个好友的头像、好友的昵称、以及一句预览信息。
大致如下:
我们就需要编写一个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_OBJECT
public:
explicit SessionFriendArea(QWidget *parent = nullptr) : QWidget(parent) {
// 初始化界面等
}
void openChatWithFriend(const QString &friendName) {
// 打开与指定好友的聊天窗口
qDebug() << "Opening chat with" << friendName;
}
// 其他成员和方法...
};
接下来,我们定义 SessionFriendItem
类,并在构造函数中使用 owner
参数。
class SessionFriendItem : public QWidget {
Q_OBJECT
public:
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
参数的作用和使用方式。
那么这一集我们先讲到这里。