我们曾经用Qt的QListWidget控件实现了 模拟微信联系人列表,今天利用该控件实现一个比较简单的错误消息的汇总显示组件。
该组件默认隐藏,显示时在桌面的右下角弹出。比较符合一般软件的设计方案。因为是比较通用的错误消息的汇总中心,因此,对错误是不进行处理的,只做消息的显示。错误消息由谁创建则由谁关闭,实现良性的闭环。
先来看下整体的效果图。
效果是很丑的样子,已经尽力了。
1、消息内容
-
消息的状态
消息的状态显示为消息是否被阅读,我们使用给每条消息添加红色圆点来标记消息是否已阅。
-
消息标题
每条消息都应该有标题,并且标题能够清晰的反应该条错误的类型,比如:server disconnected.
-
消息编码
消息的编码应该是软件设计过程中不可缺少的部分,比如网站请求的错误编码:404、502这些,我们一眼就能够大概得知是什么错误。
-
具体信息
具体信息主要包含错误信息,详细描述错误。
-
解决方案
针对错误消息提出可行的解决方案
-
时间
错误出现的时间,这个元素是必不可少的。
为了方便设计,我们采用了每条消息均是一个独立的个体,完全保存自己的所有信息,当被点击后,将自己信息反馈上来进行界面展示。这样方便管理,也方便开发。
enum SystemErrorType{
SYSTEM_INIT = 0, //消息错误码
SERVICE_DISCONNECT
...
};
enum ErrorStatus{
NOT_READ = 0, //消息的两种状态
HAVE_READ
};
下面是一个消息的实体,包含了消息所需要的基本信息,新增加了一个是否可由用户删除的标志。是因为,有些提示性的消息是可以阅后由用户直接关闭的。
struct ErrorInfo
{
SystemErrorType code;
QString info;
QString solution;
QDateTime time;
bool deleted;
ErrorInfo() : code(SYSTEM_INIT), info(), solution(), time(QDateTime::currentDateTime()), deleted(false)
{
}
};
具体的消息列表和消息体的实现不再进行赘述了,如果想看的话,可以看看前面的文章Qt实现模拟微信联系人列表。两者的实现是同样的道理。
2、消息的创建
int MessageCenter::pushError(const QString& strErrorName, const ErrorInfo& errInfo, bool isStick)
{
//先创建一条消息
auto pError = new MsgItem(this);
pError->setErrorText(strErrorName);
pError->setErrorInfo(errInfo);
pError->setErrorStatus(NOT_READ);
pError->setcleanBtnVisible(errInfo.deleted);
pError->setMsgId(++m_nMsgId);
auto pItem = new QListWidgetItem(ui->listWidget);
pItem->setSizeHint(QSize(196, 40));
//消息置顶
if (isStick)
{
ui->listWidget->insertItem(1, pItem);
}
else
{
ui->listWidget->addItem(pItem);
}
ui->listWidget->setItemWidget(pItem, pError);
m_mError.insert(m_nMsgId, pItem);//维护一份消息ID和消息体的关系,方便后续的消息的关闭
//通知应用的主题,错误消息的数量改变,让应用主题进行自行变更
emit signal_errorCount(ui->listWidget->count());
if (!isVisible())
{
show();
}
if (errInfo.deleted)
{
//如果是提示性消息,则需要显示删除按钮
connect(pError, &MsgItem::signal_delete, this, &MessageCenter::slot_delete);
}
return m_nMsgId; //返回消息ID,消息ID由创建者管理
}
3、消息关闭
消息关闭时,主要进行资源的管理和界面信息的清理。
void MessageCenter::closeError(int nMsgId)
{
QListWidgetItem* pError = m_mError.value(nMsgId);
if (m_pCurrentItem == pError)
{
m_pCurrentItem = Q_NULLPTR;
}
QListWidgetItem *pItem = ui->listWidget->takeItem(ui->listWidget->row(pError));
m_mError.remove(nMsgId);
resetPage();
delete pItem;
pItem = Q_NULLPTR;
if (m_mError.isEmpty()) //如果错误消息为空,则隐藏界面
{
hide();
ui->widgetInfo->setVisible(false);
}
emit signal_errorCount(ui->listWidget->count());
}
4、右下角显示
void MessageCenter::showEvent(QShowEvent*)
{
QRect rect = QApplication::desktop()->availableGeometry();
move(rect.width() - this->size().width() - 1, rect.height() - this->size().height() - 1);
}
代码测试。