在 Qt 中窗口的显示是需要指定位置的,这个位置是通过坐标来确定的,所有坐标的选取都是基于坐标原点来确定的,Qt的坐标原点在窗口的左上角。
在一个 Qt 窗口中一般都有很多子窗口内嵌到这个父窗口中,其中每个窗口都有自己的坐标原点,子窗口的位置也就是其使用的坐标点就是它的父窗口坐标体系中的坐标点。
在 Qt 的某一个窗口中有可能有若干个控件,这个控件都是嵌套的关系,A 窗口包含 B 窗口,B 窗口包含 C 窗口。每个窗口都有坐标原点,在左上角,子窗口的位置是基于父窗口的坐标体系来确定的,通过父窗口左上角的坐标点来确定自己的位置。Qt 中窗口显示的时候使用的相对坐标,相对于自己的父窗口将子窗口移动到父窗口的某个位置。
移动窗口函数:
// 参数 x, y是要移动的窗口的左上角的点, 窗口的左上角移动到这个坐标点
void QWidget::move(int x, int y);
void QWidget::move(const QPoint &);
ui->setupUi(this);
this->move(200,200); // 主窗口移动
//创建一个按钮,让这个按钮作为主窗口的子控件
QPushButton* bta = new QPushButton(this);
//移动按钮的位置
bta->move(10,10);
//设置按钮的大小
bta->setFixedSize(200,200);
//创建按钮B,让这个按钮作为按钮A的子控件
QPushButton* btb = new QPushButton(bta);
btb->move(10,10);
btb->setFixedSize(100,100);
QObject 是以对象树的形式组织起来的。当创建QObject对象时,会看到QObject的构造函数接收一个QObject指针作为参数(parent,父对象指针)。在创建 QObject 对象时,可以提供一个其父对象,创建的这个 QObject 对象会自动添加到其父对象的 children () 列表。当父对象析构的时候,列表中的所有对象也会被析构。(注意,这里的父对象并不是继承意义上的父类)
QWidget 是能够在屏幕上显示的一切组件的父类。QWidget 继承自 QObject,因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件。因此,它会显示在父组件的坐标系统中,被父组件的边界剪裁。
当用户关闭一个对话框的时候,应用程序将其删除,那么,属于这个对话框的按钮、图标等应该一起被删除,因为这些都是对话框的子组件。
Qt 引入对象树的概念,在一定程度上解决了内存问题。
当一个 QObject 对象在堆上创建的时候,Qt 会同时为其创建一个对象树。对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。
任何对象树中的 QObject 对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的 children () 列表中删除;如果有孩子,则自动 delete 每一个孩子。
Qt中有内存回收机制, 但是不是所有被new出的对象被自动回收, 满足条件才可以回收:
①创建的对象必须是 QObject 类的子类
QObject 类是没有父类的,Qt 中大部分类都是从这个类派生出去的,Qt 中使用频率很高的窗口类和控件都是 QObject 的直接或间接的子类
②创建出的类对象,必须要指定其父对象
指定父对象有两种方式:
// 方式1: 通过构造函数
// parent: 当前窗口的父对象, 找构造函数中的 parent 参数即可
QWidget::QWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
QTimer::QTimer(QObject *parent = nullptr);
// 方式2: 通过setParent()方法
// 假设这个控件没有在构造的时候指定符对象, 可以调用QWidget的api指定父窗口对象
void QWidget::setParent(QWidget *parent);
void QObject::setParent(QObject *parent);
Qt 是一个 C++ 框架,因此 C++ 中所有的语法和数据类型在 Qt 中都是被支持的,但是 Qt 中也定义了一些属于自己的数据类型。
Qt基本数据类型定义在
一般还是使用C++类型的数据类型。
在 Qt 中进行 log 输出,Qt 框架提供了专门用于日志输出的类,头文件名为
qDebug() << "xxxxx" << xxxxxx;
和qDebug()类似的日志函数还有qWarning(),qInfo(),qCritical()。
若想要通过终端输出调试需要在项目文件config配置项中添加console控制台属性,重新构建项目即可。
CONFIG += c++11 console
在 Qt 中不仅支持 C, C++ 中的字符串类型,而且还在框架中定义了专属的字符串类型,我们必须要掌握在 Qt 中关于这些类型的使用和相互之间的转换。
语言类型 | 字符串类型 |
C | char* |
C++ | std::string char* |
Qt | QByteArray,QString |
在 Qt 中 QByteArray 可以看做是 c 语言中 char* 的升级版本。在使用这种类型的时候可通过这个类的构造函数申请一块动态内存,用于存储我们需要处理的字符串数据。
1.构造函数
// 构造空对象, 里边没有数据
QByteArray::QByteArray();
// 将data中的size个字符进行构造, 得到一个字节数组对象
// 如果 size==-1 函数内部自动计算字符串长度, 计算方式为: strlen(data)
QByteArray::QByteArray(const char *data, int size = -1);
// 构造一个长度为size个字节, 并且每个字节值都为ch的字节数组
QByteArray::QByteArray(int size, char ch);
2.在尾部追加数据
QByteArray &QByteArray::append(const QByteArray &ba);
void QByteArray::push_back(const QByteArray &other);
3.清空
// 将对象中的数据清空, 使其为null
void QByteArray::clear();
4.遍历
// 使用迭代器
iterator QByteArray::begin();
iterator QByteArray::end();
// 使用数组的方式进行遍历
// i的取值范围 0 <= i < size()
char QByteArray::at(int i) const;
char QByteArray::operator[](int i) const;
5.查看字节数组对象中字节的个数
int QByteArray::length() const;
int QByteArray::size() const;
int QByteArray::count() const; //若传入参数,返回字符出现的次数
QString 封装字符串,但是内部的编码为 utf8, UTF-8 属于 Unicode 字符集,它固定使用多个字节(window为2字节, linux为3字节)来表示一个字符。
1.构造函数
// 构造一个空字符串对象
QString::QString();
// 将 char* 字符串 转换为 QString 类型
QString:: (const char *str);
// 将 QByteArray 转换为 QString 类型
QString::QString(const QByteArray &ba);
其他的操作如追加,查看字符的个数,清除内存方式都是一样的。注意这里的size()求的是字符的个数(1个汉字算一个字符,3个字节),不是字节的长度。
char,std::string,QByteArray,QString几者之间类型的转换
QByteArray相关类型转换:
// 将QByteArray类型的字符串 转换为 char* 类型
char *QByteArray::data();
const char *QByteArray::data() const;
// int, short, long, float, double -> QByteArray
QByteArray &QByteArray::setNum(int n, int base = 10);
[static] QByteArray QByteArray::number(int n, int base = 10);
// QByteArray -> int, short, long, float, double
int QByteArray::toInt(bool *ok = Q_NULLPTR, int base = 10) const;
float QByteArray::toFloat(bool *ok = Q_NULLPTR) const;
double QByteArray::toDouble(bool *ok = Q_NULLPTR) const;
// std::string -> QByteArray
[static] QByteArray QByteArray::fromStdString(const std::string &str);
// QByteArray -> std::string
std::string QByteArray::toStdString() const;
QString相关类型转换
// 将int, short, long, float, double 转换为 QString 类型
QString &QString::setNum(int n, int base = 10);
[static] QString QString::number(int n, int base = 10);
// 将 QString 转换为 int, short, long, float, double 类型
int QString::toInt(bool *ok = Q_NULLPTR, int base = 10) const;
double QString::toDouble(bool *ok = Q_NULLPTR) const;
// 将标准C++中的 std::string 类型 转换为 QString 类型
[static] QString QString::fromStdString(const std::string &str);
// 将 QString 转换为 标准C++中的 std::string 类型
std::string QString::toStdString() const;
// QString -> QByteArray
// 转换为本地编码, 跟随操作系统
QByteArray QString::toLocal8Bit() const;
// 转换为 Latin-1 编码的字符串 不支持中文
QByteArray QString::toLatin1() const;
// 转换为 utf8 编码格式的字符串 (常用)
QByteArray QString::toUtf8() const;
字符串拼接函数QString::arg()
QString QString::arg(const QString &a,
int fieldWidth = 0,
QChar fillChar = QLatin1Char( ' ' )) const;
QString QString::arg(int a, int fieldWidth = 0,
int base = 10,
QChar fillChar = QLatin1Char( ' ' )) const;
QString str = QString("时间:%1 温度:%2 湿度:%3")
.arg("11:30").arg(37.3).arg(34);
qDebug()<
QVariant 充当着最常见的数据类型的联合。QVariant 可以保存很多 Qt 的数据类型和c++的基本数据类型。
//将标准类型转换为 QVariant 类型
1.使用QVariant类的构造函数
QVariant::QVariant(int val);
QVariant::QVariant(double val);
QVariant::QVariant(const QByteArray &val);
2.使用设置函数将支持的数据类型设置到QVariant对象中
void QVariant::setValue(const T &value); // T类型:QVariant支持的类型
[static] QVariant QVariant::fromValue(const T &value);
判断 QVariant 中封装的实际数据类型
//该函数的返回值是一个枚举类型, 可通过这个枚举判断出实际是什么类型的数据
Type QVariant::type() const; //返回值enum QVariant::type
将 QVariant 对象转换为实际的数据类型
使用QVariant类提供的 toxxx() 方法
QByteArray QVariant::toByteArray() const;
int QVariant::toInt(bool *ok = Q_NULLPTR) const;
除了以上变量类型还支持使用 QVariant 类进行封装,被QVariant存储的数据类型需要有一个默认的构造函数和一个拷贝构造函数。为了实现这个功能,必须使用 Q_DECLARE_METATYPE() 宏。通常会将这个宏放在类的声明所在头文件的下面, 原型为:Q_DECLARE_METATYPE(Type)。
// *.h
struct MyTest
{
int id;
QString name;
};
// 自定义类型注册
Q_DECLARE_METATYPE(MyTest)
// *.cpp
MyTest t;
t.name = "ming";
t.num = 999;
// 值的封装
QVariant vt = QVariant::fromValue(t);
// 值的读取
if(vt.canConvert()) //判读 QVariant对象可转换为对应的模板类型T
{
MyTest t = vt.value(); //读取实际的值
qDebug() << "name: " << t.name << ", num: " << t.num;
}
// 如果当前QVariant对象可用转换为对应的模板类型 T, 返回true, 否则返回false
bool QVariant::canConvert() const;
// 将当前QVariant对象转换为实际的 T 类型
T QVariant::value() const;
QPoint 类封装了常用的坐标点 (x, y)。
// 构造函数
QPoint::QPoint(); // 构造一个坐标原点, 即(0, 0)
QPoint::QPoint(int xpos, int ypos); // 参数为 x轴坐标, y轴坐标
// 设置x轴坐标
void QPoint::setX(int x);
// 设置y轴坐标
void QPoint::setY(int y);
// 得到x轴坐标
int QPoint::x() const;
// 得到x轴坐标的引用
int &QPoint::rx();
// 得到y轴坐标
int QPoint::y() const;
// 得到y轴坐标的引用
int &QPoint::ry();
QLine 是一个直线类,封装了两个坐标点。
// 构造函数
QLine::QLine();// 构造一个空对象
QLine::QLine(const QPoint &p1, const QPoint &p2); // 构造一条直线, 通过两个坐标点
QLine::QLine(int x1, int y1, int x2, int y2);// 从点 (x1, y1) 到 (x2, y2)、
// 给直线对象设置坐标点
void QLine::setPoints(const QPoint &p1, const QPoint &p2);
// 起始点(x1, y1), 终点(x2, y2)
void QLine::setLine(int x1, int y1, int x2, int y2);
// 设置直线的起点坐标
void QLine::setP1(const QPoint &p1);
// 设置直线的终点坐标
void QLine::setP2(const QPoint &p2);
// 返回直线的起始点坐标
QPoint QLine::p1() const;
// 返回直线的终点坐标
QPoint QLine::p2() const;
// 返回值直线的中心点坐标, (p1() + p2()) / 2
QPoint QLine::center() const;
// 返回值直线起点的 x 坐标
int QLine::x1() const;
// 返回值直线终点的 x 坐标
int QLine::x2() const;
// 返回值直线起点的 y 坐标
int QLine::y1() const;
// 返回值直线终点的 y 坐标
int QLine::y2() const;
// 用给定的坐标点平移这条直线
void QLine::translate(const QPoint &offset);
void QLine::translate(int dx, int dy);
// 用给定的坐标点平移这条直线, 返回平移之后的坐标点
QLine QLine::translated(const QPoint &offset) const;
QLine QLine::translated(int dx, int dy) const;
QSize 类用来形容长度和宽度。
// 构造函数
QSize::QSize();// 构造空对象, 对象中的宽和高都是无效的,需要自己设置
QSize::QSize(int width, int height); // 使用宽和高构造一个有效对象
其余函数和上面的类似可查看文档。
QRect 类来描述一个矩形。
// 构造函数
QRect::QRect(); // 构造一个空对象
// 基于左上角坐标, 和右下角坐标构造一个矩形对象
QRect::QRect(const QPoint &topLeft, const QPoint &bottomRight);
// 基于左上角坐标, 和 宽度, 高度构造一个矩形对象
QRect::QRect(const QPoint &topLeft, const QSize &size);
// 通过 左上角坐标(x, y), 和 矩形尺寸(width, height) 构造一个矩形对象
QRect::QRect(int x, int y, int width, int height);
QDate 类可以封装日期信息也可以通过这个类得到日期相关的信息,包括: 年 , 月 , 日。
// 构造函数
QDate::QDate();
QDate::QDate(int y, int m, int d);
// 重新设置日期对象中的日期
bool QDate::setDate(int year, int month, int day);
// 给日期对象添加 ndays 天
QDate QDate::addDays(qint64 ndays) const;
// 得到日期对象中的年/月/日
int QDate::year() const;
void QDate::getDate(int *year, int *month, int *day) const;
日期对象格式化:
d-作为数字的一天,不带前导零(1到31)
dd-以数字形式表示的日期,前导零(01到31)
ddd-缩写星期几,例如“Mon”到“Sun”
dddd-不缩写,例如“'Monday”到“Sunday”
M-作为数字的月份,没有前导零(1到12)
MM-以数字形式表示的月份,前导零(01到12)
MMM-缩写月份名称,Jan
MMMM-不缩写月份名称,January
yy-以两位数表示的年份(00到99)
yyyy-以四位数表示的年份。如果年份为负数,则在前面加一个负号,表示五个字符。
配合上面的格式和使用QString QDate::toString(const QString &format) const;可以实现日期的格式化输出。
获取本地的当前时间:
[static] QDate QDate::currentDate();
//获取日期
QDate d = QDate::currentDate();
QString data_str = d.toString("yyyy-MM-dd");
qDebug()<<"data:"<
QTime 类可以封装时间信息可以通过这个类得到时间相关的信息,包括: 时 , 分 , 秒 , 毫秒。
// 构造函数
QTime::QTime();
// h: 0 ~ 23 m:0 ~ 59 ms:0 ~ 999
QTime::QTime(int h, int m, int s = 0, int ms = 0);
/ 阶段性计时
void QTime::start(); //开始计时
int QTime::elapsed() const; // 计时结束
int QTime::restart();// 重新计时
// 推荐使用的API函数,QElapsedTimer 类
void QElapsedTimer::start();
qint64 QElapsedTimer::restart();
qint64 QElapsedTimer::elapsed() const;
//得到当前时间
[static] QTime QTime::currentTime();
时间格式化
h==>无前导零的小时(如果显示上午/下午,则为0到23或1到12)
hh==>前导零的小时数(如果显示上午/下午,则为00到23或01到12)
H==>没有前导零的小时(0到23,即使有AM/PM显示)
HH==>前导零的小时数(00到23,即使有AM/PM显示)
m==>没有前导零的一分钟(0到59)
mm==>前导零(00到59)的分钟
s==>整秒,没有任何前导零(0到59)
ss==>整秒,适用时前导零(00到59)
zzz==>秒的小数部分,精确到毫秒,
包括适用的尾随零(000至999)
AP或A==>使用上午/下午(大写) 描述上下午, 中文系统显示汉字
ap或a==>使用上午/下午(小写) 描述上下午, 中文系统显示汉字
时间格式化配合QString QTime::toString(const QString &format) const;可以实现时间格式的输出。
//获取时间
QTime t = QTime::currentTime();
QString time_str = t.toString("hh:mm:ss.zzz");
qDebug()<<"time:"<
QDateTime 类可以封装日期和时间信息,可以通过这个类得到日期和时间相关的信息这个类就是 QDate 和 QTime 这两个类的结合体。
// 构造函数
QDateTime::QDateTime();
QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec = Qt::LocalTime);
// 设置日期
void QDateTime::setDate(const QDate &date);
// 设置时间
void QDateTime::setTime(const QTime &time);
// 得到当前时区的日期和时间(本地设置的时区对应的日期和时间)
[static] QDateTime QDateTime::currentDateTime();