UI、常用类、多窗口编程

一、UI进阶

1. Designer 设计师

Designer是Qt内置的UI设计工具,可以独立启动,也可以在Qt Creator中使用,其文件格式为.ui。

使用Qt Creator创建项目时,勾选创建界面选项,新创建的项目中的Dialog类会自带一个界面文件,双击即可使用内置的Designer程序打开此文件。

Designer程序的各个区域如下所示。

2. 布局 Layout

可以认为布局是一个透明的盒子,内部可以放置不同的组件对象,这些对象在布局中会按照预设的效果自动排布。

布局有四种:

  • 垂直布局
  • 水平布局
  • 格点布局
  • 表单布局

当布局贴合窗口时,可能会造成组件间距变小的情况,此时可以使用伸展器组件填充空白区域。

伸展器组件本身是不可见的。

选中布局,可以在右下角配置其属性值。

布局和布局之间可以嵌套,内层布局相当于外层布局的一个组件。虽然布局可以嵌套,但是应该在实际开发中尽量避免嵌套。

3. QWidget属性

只要是QWidget的派生类对象在Designer中存在,选中此对象后,都可以在右下角的属性配置面板中找到黄色的属性。

4. UI指针

ui指针是Qt通过Designer管理组件对象的一种方式,其原理如下所示。

5. 基础组件

5.1 标签 QLabel

用于显示图片或文字。

导入图片到Qt中作为资源的步骤如下:

1. 下载图片并命名为英文小写+下划线+数字的组合,数字不能开头。注意图片不要过大。

2. 把图片放置到工作目录下。

3. 在Qt Creator中选中项目名称,鼠标右键,点击“添加新文件”。

4. 在弹出的窗口中,按照下图所示进行操作。

5. 在弹出的窗口中,按照下图所示进行操作。

6. 在项目管理界面直接点击完成,可以看到项目中会创建一个资源文件,扩展名为qrc

7. 选中qrc资源文件,点击“添加前缀”。

8. 再次选中qrc文件,点击“添加文件”,在弹出的对话框中导入图片文件即可,后续添加图片可以直接从当前步骤开始操作。

9. 可以在qrc文件中看到已经导入的图片。

10. 如果要在Designer中使用此图片,则需要重新构建一次项目;如果要在C++代码中使用此图片,则需要选中在qrc中的图片后,鼠标右键,点击“复制资源路径到剪切板”。

5.2 按钮类

按钮类组件的继承关系如下所示。

这几个按钮类都继承自QAbstractButton类,QAbstractButton是一个抽象类,内部规定了按钮的基本功能框架。

QAbstractButton的常用属性如下所示。

按钮显示的图片通常为图标,可以从下面的网站下载:

iconfont-阿里巴巴矢量图标库

同级互斥,同级可以使用布局,也可以使用QGroupBox组件。

QAbstractButton常用信号函数如下所示。

如果一个窗口内部有若干个按钮对象,需要给这些按钮对象都设置信号槽连接,可以分别给每个按钮对象进行信号槽的连接。此时可以使用QButtonGroup类给若干个按钮进行编组后统一进行信号槽连接处理。

QButtonGroup直接继承QObject类,因此不可见,也不属于ui指针管理,需要在代码汇总手动创建和销毁。

  • QButtonGroup::QButtonGroup(QObject * parent = 0)

        构造函数

  • void QButtonGroup::addButton(QAbstractButton * button, int id = -1)

        添加按钮到按钮组

        参数1:添加的按钮对象

        参数2:按钮编号,正数且不重复

  • void QButtonGroup::buttonToggled(int id, bool checked) [signal]

        按钮组中的按钮对象选中状态改变时发射的信号函数

        参数1:状态改变的按钮对象的编号

        参数2:当前此按钮的选中状态

需要注意的是,QCheckBox编组后会变为互斥,需要使用下面的函数解除互斥:

void setExclusive(bool)

参数:是否互斥

5.3 单行文本编辑框 QLineEdit

用于录入一行的用户输入内容。

QLineEdit的常用属性如下所示。

QLineEdit的常用信号函数如下所示。

5.4 组合框 QComboBox

类似于QRadioButton,组合框提供了另一种单选的方式。

QComboBox常用属性如下所示。

QComboBox常用信号函数如下所示。

5.5 一组与数字相关的组件

以下组件都与数字有关。

这些组件常用的属性如下所示。

这些组件常用的信号函数如下所示。

  • void valueChanged(int value)

        当前数值发生变化时发射的信号

二、常用类

1. QString 字符串类

QString是Qt中的字符串类,使用Unicode编码,而不是ASCII码。在C++中字符使用8位的char类型表示一个字符,但是在Qt中使用16位的QChar表示一个字符。因此Qt处理中文没有任何问题,并且一个汉字算作一个字符。

QString类整体使用与std::string类似,但是在API上有所不同。

常用函数如下:

  • QString QString::number(int n, int base = 10) [static]

        数字→字符串

        参数1:要转换的数字

        参数2:进制

  • QString & QString::setNum(int n, int base = 10)

        数字→字符串,支持链式调用

        参数1:要转换的数字

        参数2:进制

  • int QString::toInt(bool * ok = 0, int base = 10) const

        字符串→数字

        参数1:转换的结果,成功或失败

        参数2:进制

        返回值:转换的结果,数字;如果失败,返回0。

dialog.app

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    QString str = "你好吗αβγāáǎàあいうㅞㅝ";
    qDebug() << str.size();
    for(int i=0;i<str.size();i++)
    {
        qDebug() << str.at(i);
    }

    // 判断字符串是否为空
    qDebug() << str.isEmpty();
    str.append("fdf");
    qDebug() << str;

    // 基于16进制转换
    int i = 16;
    qDebug() << QString::number(i,16);

    // 支持链式调用的转换
    qDebug() << str.setNum(255,16).prepend("0x");

    str = "0";
    bool result; // 转换成功或失败的结果
    // QString → int
    int m = str.toInt(&result,10);
    if(result)
        qDebug() << "转换成功:" << m;
    else
        qDebug() << "转换失败:" << m;
}

Dialog::~Dialog()
{
    delete ui;
}

由于QString类函数众多,无需死记每个函数,只需要把常用的函数单词记住,随用随查即可。

2. 容器类

Qt重新实现了C++中的容器类,这些容器类比C++中STL的容器类更加轻巧、安全和易于使用,使用Qt的容器类可以减少可执行文件的大小,Qt的容器类是线程安全的,在基本兼容C++的容器类接口的基础上拓展了新的接口。

分别以QList和QMap为例,进行顺序容器和关联容器的讲解。

2.1 QList

自定义一个C++类,作为QList的元素类型。

下面是创建自定义的C++类的步骤:

1. 在Qt Creator中选中项目名称,鼠标右键,点击“添加新文件”。

2. 在弹出的窗口中,按照下图所示进行操作。

3. 在弹出的窗口中,输入类名后点击“下一步”。

4. 在项目管理界面,直接点击“完成”。可以看到项目中多了新创建的类的头文件和源文件。

需要注意的是,QStringList类型基本等同QList<QString>,后面不再赘述。

2.2 QMap

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    QMap<QString,QString> map;
    // 增加元素
    map["姓名"] = "张三";
    map["年龄"] = "22岁";
    map.insert("地址","济南市高新区");

    // Qt的容器类型,如果元素类型支持输出
    // 则可以直接输出容器对象
    qDebug() << map;



    // 取出元素之前先判断一下此键值对是否存在
    if(map.contains("姓名"))
    {
        // 修改
        map["姓名"] = "李四";
        qDebug() << map["姓名"];
    }

    // 删除
    // 失败返回0
    int result = map.remove("地址");
    if(result == 0)
        qDebug() << "移除失败";
    else
        qDebug() << "移除成功";


    // 也可以使用下面的方式取出元素,无需判断
    // 参数1:键
    // 参数2:取出失败的默认值
    QString value = map.value("地址","404");
    qDebug() << value;

    qDebug() << "------STL迭代------";
    for(QMap<QString,QString>::const_iterator iter = map.begin();
        iter != map.end();iter++)
    {
        // 分别取出键和值
        qDebug() << iter.key() << iter.value();
    }

    qDebug() << "---------Java迭代---------";
    // 读写 QMutableMapIterator<Key, T>
    // 只读 QMapIterator<Key, T>
    QMapIterator<QString, QString> iter(map);
    while(iter.hasNext())
    {
        iter.next(); // 向后移动
        // 分别取出键和值
        qDebug() << iter.key() << iter.value();
    }
}

3. 跨平台数据类型

Qt是一个跨平台的开发框架,为了确保在各个平台上的数据类型具有同一的长度,Qt为各种常用的基本数据类型定义了类型符号。

除此之外,Qt中还有一个通用数据类型QVariant,可以对常见的Qt数据类型进行相互转换,也可以使用QVariant类型作为中间类型间接转换不同数据类型。

4. 时间和日期处理

Qt拥有若干时间和日期相关类型,本次使用QDateTime类进行讲解。

QDateTime类常用函数如下所示。

  • qint64 QDateTime::currentMSecsSinceEpoch() [static]

        返回1970年1月1日 0点0分0秒到现在的毫秒数

  • QDateTime QDateTime::currentDateTime() [static]

        返回一个基于当前时区的时间和日期信息的QDateTime对象

  • QString QDateTime::toString(const QString & format) const

        返回一个自定义格式的时间日期字符串

        参数是自定义的时间和日期格式。

5. QTimer 定时器类

定时器类QTimer主要有两个功能:

  • 周期性执行某个动作
  • 延迟一段时间后执行某个动作

QTimer类与之前的QButtonGroup一样,需要手动控制堆内存对象的创建和销毁。

QTimer的常用属性如下所示。

  • interval : int

        如果是一次性的定时器,此属性表示延迟执行的时间;

        如果是周期性的定时器,此属性表示间隔执行的时间。

        时间单位毫秒。

  • singleShot : bool

       此属性表示定时器是否是一次性,如果不是一次性就是周期性。

QTImer的常用函数如下所示。

  • void QTimer::start() [slot]

        开始或重新开始定时器,如果定时器已经在运行,则会停止运行后再次运行。

  • void QTimer::stop() [slot]

       停止运行

  • void QTimer::timeout() [signal]

       定时器出发时发射的信号

三、多窗口编程

1. 消息对话框 QMessageBox

QDialog是一个对话框窗口类,Qt为了方便程序员调用各种功能的对话框窗口,预设了很多QDialog的派生类,这些派生类分别应用于不同的场景。

这些派生类往往都通过一个静态成员函数调用,通常不需要使用构造函数创建对象。根据不同窗口的功能,这些静态函数会提供当前窗口的信息作为返回值。

QMessageBox是一个用于展示信息或询问用户一个问题的模态对话框,预设的类型有四种:

Question、Information、Warning、Critical

展示QMessageBox的静态成员函数如下所示。

函数名称可以更换为question、information、warning。

参数1:父对象

参数2:窗口标题

参数3:窗口信息

返回值:用户在弹窗中点击的按钮

2. 常见窗口类的继承关系

QWidget类本身也可以创建对象,其构造函数如下所示。

  • QWidget::QWidget(QWidget * parent = 0)

        如果parent参数使用默认值,QWidget对象就是一个独立的窗口;

        如果parent参数不使用默认值,QWidget对象会成为其父窗口对象内部的组件。

QMainWidow类通常作为主窗口,因为此类可以增加菜单栏、工具栏、状态栏等。

QWidget类内部也有一些所有的窗口类共有的成员,例如:

  • windowTitle : QString

        窗口标题

  • windowFlags : Qt::WindowFlags

        窗口标记

  • void QWidget::setWindowState(Qt::WindowStates windowState)

        设置窗口状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值