Qt实践录:一些界面设计的记录示例

本文主要记录使用 Qt 实现某一些小功能的示例。

控件特定条件下显示

有些场合,需要隐藏界面某些功能,面向特定人员使用,如一些维护升级工具,面向现场支持人员和面向开发人员,所用之功能不同,但又不想同时维护多个工具,则可以隐藏部分功能。
本节演示双击某个提示语(使用 QLabel),再显示另一个按钮的功能。
0、设计
界面有2个控件:一为 QLabel,控件名称为lbShow,显示提示语(文字可以为空,放置某个角落),一为 QPushButton,控件名称为btnRegister,表示某个功能的按钮。
1、声明(实际为重载)事件过滤函数eventFilter

1
bool eventFilter(QObject *watched, QEvent *event);

2、隐藏按钮,针对lbShow安装事件过滤器:

1
2
3
4
// 先隐藏注册按钮
ui->btnRegister->hide();
// 显示注册按钮的触发事件:// 双击左上方控件显示
ui->lbShow->installEventFilter(this);

3、实现事件过滤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

bool DialogDemo::eventFilter(QObject *watched, QEvent *event)
{
// 针对lbShow控件
if (watched == ui->lbShow)
{
//判断双击事件
if (event->type() == QEvent::MouseButtonDblClick)
{
// 双击显示
ui->btnRegister->show();
return true;
}
else
{
return false;
}
}
else
{
return QWidget::eventFilter(watched, event);
}
}

关于eventFilter函数实现形式及返回值,可参考 Qt助手。一般来说,当自定义的事件处理完毕需要返回 true,如果不是监控的控件,交回父类处理。

扩展1:关于eventFilter函数,其作用远超上文所述,理论上可以监听检测很多按钮的各种事件,如状态栏的 QLabel 单击,QLabel 画图,等等。(笔者暂时未能大量实验)
扩展2:本节仅提出一种简单的隐藏方法,实际上,可以点击三次、四次,甚至五六次某个地方(如某个图标,某个按钮旁边),实现方式实质是监控触发的事件,再进行按钮的显示,而且,还可以使用密码授权。当然,安全和便利是矛盾体,要适当取舍。

状态栏

对于 MainWindow,Qt 设计师中有几个默认布局,中间为路面窗体,最上方为标题栏,其下为工具栏,最下方为状态栏。——这也是一般应用程序的样式。状态栏无法在设计师中拖放控件,虽是缺点,但也是优点,因为可以通过封装的函数,直接复用于项目中,当然还需要根据实际情况进行适当修改。本节给出一个简单的模板,内容有:
左侧为信息提示,接着是数据显示(如收发计数、字数、行号),右侧是系统时间,接着是版权或提示语,接着是退出图标按钮。
这些内容,均可以自由定制,不用拘泥,适合实际需求的方是最佳的。
关于状态栏的几个技术要点:
1、MainWindow 默认有 QStatusBar对象,名为 statusbar。
2、提示信息使用showMessage函数,可指定显示的时长。
3、使用addPermanentWidget添加部件,否则临时提示信息会将其覆盖掉。
下面是示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
    // 状态栏相关
QLabel* m_stsDebugInfo1;
QLabel* m_stsDebugInfo2;
QLabel* m_stsSysTime;
QLabel* m_stsCopyright;
QLabel* m_stsExit;

void MainWindow::initStatusBar2()
{
// 状态栏分别为:
// 临时信息
// 提示信息(可多个)
// 系统时间
// 版本信息(或版权声明)
// 退出图标
m_stsDebugInfo1 = new QLabel();
m_stsDebugInfo2 = new QLabel();
m_stsSysTime = new QLabel();
m_stsCopyright = new QLabel();
m_stsExit = new QLabel();

m_stsDebugInfo1->setMinimumWidth(100);
ui->statusbar->addPermanentWidget(m_stsDebugInfo1);
m_stsDebugInfo1->setText("cnt: 250");

m_stsDebugInfo2->setMinimumWidth(100);
ui->statusbar->addPermanentWidget(m_stsDebugInfo2);

ui->statusbar->showMessage(tr("临时信息!"), 500);

QDateTime dateTime(QDateTime::currentDateTime());
QString timeStr = dateTime.toString("yyyy-MM-dd HH:mm:ss.zzz");
m_stsSysTime->setText(timeStr);
ui->statusbar->addPermanentWidget(m_stsSysTime);

// 版权信息
m_stsCopyright->setFrameStyle(QFrame::NoFrame);
m_stsCopyright->setText(tr(" <a href=\"https://www.latelee.org\">技术主页</a> "));
m_stsCopyright->setOpenExternalLinks(true);
ui->statusbar->addPermanentWidget(m_stsCopyright);

// 退出图标
m_stsExit->installEventFilter(this); // 安装事件过滤,以便获取其单击事件
m_stsExit->setToolTip("Exit App");
// 贴图
QPixmap exitIcon(":/images/exit.jpg");
m_stsExit->setMinimumWidth(22);
m_stsExit->setPixmap(exitIcon);
ui->statusbar->addPermanentWidget(m_stsExit);

connect(this, &MainWindow::sig_exit, qApp, &QApplication::quit); // 直接关联到全局的退出槽
}