Qt 教程二(二)

简介: Qt 教程二(二)

Qt 教程二(二)


4. QVariant

QVariant(变体数据类型)这个类很神奇,或者说方便。很多时候,需要几种不同的数据类型需要传递,如果用结构体,又不大方便,容器保存的也只是一种数据类型,而QVariant则可以统统搞定。

QVariant 这个类型充当着最常见的数据类型的联合。QVariant 可以保存很多Qt的数据类型,包括QBrush、QColor、QCursor、QDateTime、QFont、QKeySequence、 QPalette、QPen、QPixmap、QPoint、QRect、QRegion、QSize和QString,并且还有C++基本类型,如int、float等。

4.1 标准类型

将标准类型转换为QVariant类型

// 这类转换需要使用QVariant类的构造函数, 由于比较多, 大家可自行查阅Qt帮助文档, 在这里简单写几个
QVariant(int val);
QVariant(bool val);
QVariant(double val);
QVariant(const char *val);
QVariant(const QByteArray &val);
QVariant(const QString &val);
......
// 使用设置函数也可以将支持的类型的数据设置到QVariant对象中
// 这里的 T 类型, 就是QVariant支持的类型
void setValue(const T &value);
// 该函数行为和 setValue() 函数完全相同
[static] QVariant fromValue(const T &value);

Exmple

QVariant v(5);
QVariant v;
v.setValue(5);
QVariant v = QVariant::fromValue(5);
int i = v.toInt();          // i is now 5
QString s = v.toString();   // s is now "5"

判断 QVariant中封装的实际数据类型

Type 是枚举类型

//获取类型,返回的是一个枚举类型;如QVariant::Int ...
Type type() const;
//获取类型名
const char *typeName() const;
//根据类型id(枚举)获取类型名(字符串)
[static] const char *typeToName(int typeId);
//根据类型名(字符串)获取类型id(枚举)
[static] Type nameToType(const char *name);

将QVariant对象转换为实际的数据类型

//在转换之前可以先判断能够转换成对应的类型
bool canConvert(int targetTypeId) const
bool canConvert() const
bool    toBool() const;
QByteArray  toByteArray() const;
double    toDouble(bool *ok = Q_NULLPTR) const;
float     toFloat(bool *ok = Q_NULLPTR) const;
int     toInt(bool *ok = Q_NULLPTR) const;
QString   toString() const;
......
T value() const
//v.value<int>();       

4.2 自定义类型

除了标准类型, 我们自定义的类型也可以使用QVariant类进行封装, 被QVariant存储的数据类型需要有一个默认的构造函数和一个拷贝构造函数。为了实现这个功能,首先必须使用Q_DECLARE_METATYPE()宏。通常会将这个宏放在类的声明所在头文件的下面, 原型为:

Q_DECLARE_METATYPE(Type)

使用的具体步骤如下:

第一步: 定义类型,并注册

//自定义类型
class Animal
{
public:
    Animal(){}  //必须要有默认构造函数
                //拷贝构造函数也必须有,不过没有深、浅拷贝时,用默认的即可
    Animal(QString name):_name(name){}
    void show()
    {
        qDebug()<<"Animal show name is :"<< _name <<endl;
    }
private:
    QString _name;
};
//自定义类型注册
Q_DECLARE_METATYPE(Animal);

第二步: 使用forvalue()存储对象

int main()
{
    //QVariant vt(Animal("snake")); //不可以通过构造函数存自定义类型
    QVariant vt;
    //有以下两种方法可以,存自定义类型
    vt = QVariant::fromValue(Animal("dog"));  //①
    vt.setValue(Animal("cat"));         //②
    //如果能转换到Animal类型,就转换
    if(vt.canConvert<Animal>())
    {
        Animal animal = vt.value<Animal>();
        animal.show();
    }
  return 0;
}

操作涉及的API如下:

// 如果当前QVariant对象可用转换为对应的模板类型 T, 返回true, 否则返回false
bool canConvert() const;
// 将当前QVariant对象转换为实际的 T 类型
T value() const;

5. 位置和尺寸

在QT中我们常见的 点, 线, 尺寸, 矩形 都被进行了封装, 下边依次为大家介绍相关的类。

5.1 QPoint

QPoint类封装了我们常用用到的坐标点 (x, y), 常用的 API如下:

void QPoint::setX(int x);
void QPoint::setY(int y);
int QPoint::x() const;
int &QPoint::rx();
int QPoint::y() const;
int &QPoint::ry();
//如果x和y坐标都为0则返回true,否则返回false
bool isNull() const
//返回x()和y()的绝对值之和,传统上称为从原点到该点的向量的“曼哈顿长度”。
//(p1-p2).manhattanLength();   
int manhattanLength() const    
//返回一个交换了x和y坐标的点:   QPoint{1, 2}.transposed() // {2, 1}  
QPoint transposed() const    
// 直接通过坐标对象进行算术运算: 加减乘除
QPoint &QPoint::operator*=(float factor);
QPoint &QPoint::operator*=(double factor);
QPoint &QPoint::operator*=(int factor);
QPoint &QPoint::operator+=(const QPoint &point);
QPoint &QPoint::operator-=(const QPoint &point);
QPoint &QPoint::operator/=(qreal divisor);
...

5.2 QLine

QLine是一个直线类, 封装了两个坐标点 (两点确定一条直线)

常用API如下:

// 设置直线的起点坐标
void setP1(const QPoint &p1);
// 设置直线的终点坐标
void setP2(const QPoint &p2);
void setPoints(const QPoint &p1, const QPoint &p2);
void setLine(int x1, int y1, int x2, int y2);
QPoint p1() const;    // 返回直线的起始点坐标
QPoint p2() const;    // 返回直线的终点坐标
QPoint center() const;  // 返回值直线的中心点坐标, (p1() + p2()) / 2 
int x1() const;   // 返回值直线起点的 x 坐标
int y1() const;   // 返回值直线起点的 y 坐标
int x2() const;   // 返回值直线终点的 x 坐标
int y2() const;   // 返回值直线终点的 y 坐标
int dx() const      //返回直线向量的水平分量  
int dy() const      //返回直线向量的垂直分量  
// 用给定的坐标点平移这条直线
void translate(const QPoint &offset);
void translate(int dx, int dy);
// 用给定的坐标点平移这条直线, 返回平移之后的坐标点(不会改变这条线的坐标)
QLine translated(const QPoint &offset) const;
QLine translated(int dx, int dy) const;
// 直线对象进行比较
bool operator!=(const QLine &line) const;
bool operator==(const QLine &line) const;

5.3 QSize

在QT中QSize类用来形容长度和宽度, 常用的API如下:

void setWidth(int width)
void setHeight(int height);
int width() const;    // 得到宽度
int &rwidth();      // 得到宽度的引用
int height() const;   // 得到高度
int &rheight();     // 得到高度的引用
void transpose();     // 交换高度和宽度的值
QSize transposed() const; // 交换高度和宽度的值, 返回交换之后的尺寸信息
//返回一个大小,宽为当前大小与other的最小值,高为当前大小与other的最小值
QSize boundedTo(const QSize& oterSize)
//返回一个大小,宽为当前大小与other的最大值,高为当前大小与other的最大值    
QSize expandedTo(const QSize &otherSize) const    
/*
根据指定的模式,按给定的宽度和高度缩放矩形:  
  如果mode为Qt::IgnoreAspectRatio,则大小设置为(width, height)。  
  如果mode为Qt::KeepAspectRatio,当前大小将在内部缩放到一个尽可能大的矩形(宽度,高度),保持高宽比。  
  如果mode是Qt::KeepAspectRatioByExpanding,当前大小被缩放到一个矩形,尽可能小的外部(宽度,高度),保持长宽比。  
*/
void scale(int width, int height, Qt::AspectRatioMode mode)
void scale(const QSize &size, Qt::AspectRatioMode mode)
QSize scaled(int width, int height, Qt::AspectRatioMode mode) const
QSize scaled(const QSize &s, Qt::AspectRatioMode mode) const
// 进行算法运算: 加减乘除
QSize &operator*=(qreal factor);
QSize &operator+=(const QSize &size);
QSize &operator-=(const QSize &size);
QSize &operator/=(qreal divisor);

5.4 QRect

在Qt中使用 QRect类来描述一个矩形, 常用的API如下:

// 构造一个空对象
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);
// 设置矩形的尺寸信息, 左上角坐标不变
void QRect::setSize(const QSize &size);
// 设置矩形左上角坐标为(x,y), 大小为(width, height)
void QRect::setRect(int x, int y, int width, int height);
// 设置矩形宽度
void QRect::setWidth(int width);
// 设置矩形高度
void QRect::setHeight(int height);
// 返回值矩形左上角坐标
QPoint QRect::topLeft() const;
// 返回矩形右上角坐标
// 该坐标点值为: QPoint(left() + width() -1, top())
QPoint QRect::topRight() const;
// 返回矩形左下角坐标
// 该坐标点值为: QPoint(left(), top() + height() - 1)
QPoint QRect::bottomLeft() const;
// 返回矩形右下角坐标
// 该坐标点值为: QPoint(left() + width() -1, top() + height() - 1)
QPoint QRect::bottomRight() const;
// 返回矩形中心点坐标
QPoint QRect::center() const;
// 返回矩形上边缘y轴坐标
int QRect::top() const;
int QRect::y() const;
// 返回值矩形下边缘y轴坐标
int QRect::bottom() const;
// 返回矩形左边缘 x轴坐标
int QRect::x() const;
int QRect::left() const;
// 返回矩形右边缘x轴坐标
int QRect::right() const;
// 返回矩形的高度
int QRect::width() const;
// 返回矩形的宽度
int QRect::height() const;
// 返回矩形的尺寸信息
QSize QRect::size() const;
//调整矩形的尺寸 (左上角和右下角坐标偏移量)
void QRect::adjust(int dx1, int dy1, int dx2, int dy2)
QRect QRect::adjusted(int dx1, int dy1, int dx2, int dy2) const    

QPoint,QLine,QSize,QRect各自都还有浮点型版本的,分别是QPointF,QLineF,QSizeF,QRectF,函数基本一样

6. 日期和时间

6.1. 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;
// 给日期对象添加 nmonths 月
QDate QDate::addMonths(int nmonths) const;
// 给日期对象添加 nyears 月
QDate QDate::addYears(int nyears) const;
// 得到日期对象中的年/月/日
int QDate::year() const;
int QDate::month() const;
int QDate::day() const;
void QDate::getDate(int *year, int *month, int *day) const;
/*日期对象格式化
    d     -   没有前导零的日子 (1 to 31)  
    dd    - 前导为0的日子   (01 to 31)  
    ddd   - 显示(缩写) 周一、周二、周三、周四、周五、周六、周日   
    dddd  -   显示(完整) 星期一、星期二、星期三、星期四、星期五、星期六、星期日
    M   - 没有前导零的月份(1到12)  
    MM    - 前导零的月份(01到12)  
    MMM   - 缩写 1月、2月、3月...         
    MMMM  - 完整 一月、二月、三月...
    yy    - 两个数字的年 (00 to 99)
    yyyy  - 以四位数表示的年份
*/
QString QDate::toString(const QString &format) const;
// 操作符重载 ==> 日期比较
bool QDate::operator!=(const QDate &d) const;
bool QDate::operator<(const QDate &d) const;
bool QDate::operator<=(const QDate &d) const;
bool QDate::operator==(const QDate &d) const;
bool QDate::operator>(const QDate &d) const;
bool QDate::operator>=(const QDate &d) const;
// 静态函数 -> 得到本地的当前日期
[static] QDate QDate::currentDate();

6.2. QTime

// 构造函数
QTime::QTime();
/*
    h       ==> must be in the range 0 to 23
    m and s   ==> must be in the range 0 to 59
    ms      ==> must be in the range 0 to 999
*/ 
QTime::QTime(int h, int m, int s = 0, int ms = 0);
// 公共成员函数
// Returns true if the set time is valid; otherwise returns false.
bool QTime::setHMS(int h, int m, int s, int ms = 0);
QTime QTime::addSecs(int s) const;
QTime QTime::addMSecs(int ms) const;
// 示例代码
  QTime n(14, 0, 0);                // n == 14:00:00
  QTime t;
  t = n.addSecs(70);                // t == 14:01:10
  t = n.addSecs(-70);               // t == 13:58:50
  t = n.addSecs(10 * 60 * 60 + 5);  // t == 00:00:05
  t = n.addSecs(-15 * 60 * 60);     // t == 23:00:00
// 从时间对象中取出 时/分/秒/毫秒
// Returns the hour part (0 to 23) of the time. Returns -1 if the time is invalid.
int QTime::hour() const;
// Returns the minute part (0 to 59) of the time. Returns -1 if the time is invalid.
int QTime::minute() const;
// Returns the second part (0 to 59) of the time. Returns -1 if the time is invalid.
int QTime::second() const;
// Returns the millisecond part (0 to 999) of the time. Returns -1 if the time is invalid.
int QTime::msec() const;
// 时间格式化
/*
  -- 时
    h ==> The hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
    hh  ==> The hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
    H ==> The hour without a leading zero (0 to 23, even with AM/PM display)
    HH  ==> The hour with a leading zero (00 to 23, even with AM/PM display)
    -- 分
    m ==> The minute without a leading zero (0 to 59)
    mm  ==> The minute with a leading zero (00 to 59)
    -- 秒
    s ==> The whole second, without any leading zero (0 to 59)
    ss  ==> The whole second, with a leading zero where applicable (00 to 59)
    -- 毫秒
  zzz ==> The fractional part of the second, to millisecond precision, 
      including trailing zeroes where applicable (000 to 999).
  -- 上午或者下午
    AP or A   ==>   使用AM/PM(大写) 描述上下午, 中文系统显示汉字
    ap or a   ==>   使用am/pm(小写) 描述上下午, 中文系统显示汉字
*/
QString QTime::toString(const QString &format) const;
// 操作符重载 ==> 时间比较
bool QTime::operator!=(const QTime &t) const;
bool QTime::operator<(const QTime &t) const;
bool QTime::operator<=(const QTime &t) const;
bool QTime::operator==(const QTime &t) const;
bool QTime::operator>(const QTime &t) const;
bool QTime::operator>=(const QTime &t) const;
// 静态函数 -> 得到当前时间
[static] QTime QTime::currentTime();

经时计时器

QTime的经时计时器已经过时了,推荐使用QElapsedTimer。

//QTime已废弃的函数
// 开始计时
void QTime::start();
// 计时结束
int QTime::elapsed() const;
// 重新计时
int QTime::restart();
// 推荐使用的API函数
// QElapsedTimer 类
void QElapsedTimer::start();
qint64 QElapsedTimer::restart();
qint64 QElapsedTimer::elapsed() const;

主要的使用方法就是测量一个操作耗时多久,例子如下:

QElapsedTimer elapse;
elapse.start();
for(int i = 0;i<10000000;i++);
qDebug()<<elapse.elapsed()<<endl;

6.3. QDateTime

// 构造函数
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);
// 给当前日期对象追加 年/月/日/秒/毫秒, 参数可以是负数
QDateTime QDateTime::addYears(int nyears) const;
QDateTime QDateTime::addMonths(int nmonths) const;
QDateTime QDateTime::addDays(qint64 ndays) const;
QDateTime QDateTime::addSecs(qint64 s) const;
QDateTime QDateTime::addMSecs(qint64 msecs) const;
// 得到对象中的日期
QDate QDateTime::date() const;
// 得到对象中的时间
QTime QDateTime::time() const;
// 日期和时间格式, 格式字符参考QDate 和 QTime 类的 toString() 函数
QString QDateTime::toString(const QString &format) const;
// 操作符重载 ==> 日期时间对象的比较
bool QDateTime::operator!=(const QDateTime &other) const;
bool QDateTime::operator<(const QDateTime &other) const;
bool QDateTime::operator<=(const QDateTime &other) const;
bool QDateTime::operator==(const QDateTime &other) const;
bool QDateTime::operator>(const QDateTime &other) const;
bool QDateTime::operator>=(const QDateTime &other) const;
// 静态函数
// 得到当前时区的日期和时间(本地设置的时区对应的日期和时间)
[static] QDateTime QDateTime::currentDateTime();
目录
相关文章
|
4月前
|
存储 缓存 自然语言处理
QT基础教程(QMap和QHash)
QT基础教程(QMap和QHash)
205 0
|
1月前
|
数据可视化 算法 C++
C++ cmake工程引入qt6和Quick 教程
C++ cmake工程引入qt6和Quick 教程
38 0
|
4月前
|
数据可视化 计算机视觉
QT基础教程(图形处理)
QT基础教程(图形处理)
33 0
|
4月前
QT基础教程(文本绘制)
QT基础教程(文本绘制)
46 0
|
4月前
|
存储 数据处理 数据格式
QT基础教程(文件操作深入)
QT基础教程(文件操作深入)
45 0
|
4月前
|
编解码 区块链 Windows
QT基础教程(QPalette和QIcon)
QT基础教程(QPalette和QIcon)
50 0
|
4月前
|
存储
QT基础教程(QT中的文件操作)
QT基础教程(QT中的文件操作)
43 0
|
4月前
|
开发者 索引
QT基础教程(布局管理器)
QT基础教程(布局管理器)
74 0
|
4月前
|
数据安全/隐私保护
QT基础教程(对话框2)
QT基础教程(对话框2)
32 0
|
4月前
QT基础教程(对话框1)
QT基础教程(对话框1)
33 0

热门文章

最新文章

推荐镜像

更多