Qt君


  • 首页

  • 关于

  • 归档

  • 搜索

使用Qt获取系统版本

发表于 2019-09-09

获取Windows,Mac,IOS,Android,Linux等系统版本信息。

Qt 4版本

  可以获取到系统版本的变量或函数

  • 头文件

    1
    #include <QSysInfo>
  • 使用公有静态变量和静态方法获取Windows系统版本

    1
    2
    const WinVersion WindowsVersion
    WinVersion windowsVersion ()
  • 使用公有静态变量获取Mac系统版本

    1
    const MacVersion MacintoshVersion
  • 使用静态方法获取塞班系统版本和塞班S60系统版本

    1
    2
    S60Version s60Version ()
    SymbianVersion symbianVersion ()
  • 系统版本枚举部分预览

    1
    2
    3
    4
    enum MacVersion { MV_9, MV_10_0, MV_10_1, MV_10_2, ..., MV_YOSEMITE }
    enum S60Version { SV_S60_3_1, SV_S60_3_2, SV_S60_5_0, SV_S60_5_1, ..., SV_S60_Unknown }
    enum SymbianVersion { SV_9_2, SV_9_3, SV_9_4, SV_SF_1, ..., SV_Unknown }
    enum WinVersion { WV_32s, WV_95, WV_98, WV_Me, ..., WV_CE_based }

Qt 5.0 - Qt 5.9版本

  以下方法在Qt 5.9版本以上被官方标记为不推荐使用

  • 头文件

    1
    #include <QSysInfo>
  • 使用公有静态变量和静态方法获取Windows系统版本

    1
    2
    const WinVersion WindowsVersion
    QSysInfo::WinVersion windowsVersion()
  • 使用公有静态变量和静态方法获取Mac系统版本

    1
    2
    const MacVersion MacintoshVersion
    QSysInfo::MacVersion macVersion()
  • 系统版本枚举部分预览

    1
    2
    enum MacVersion { MV_9, MV_10_0, MV_10_1, MV_10_2, ..., MV_None }
    enum WinVersion { WV_32s, WV_95, WV_98, WV_Me, ..., WV_None }

Qt 5.4 版本以上(推荐使用)

  • 头文件

    1
    #include <QSysInfo>
  • 获取系统类型

    1
    2
    3
    QString productType()
    // windows, macos, osx, android, ios,
    // tvos, debian, winrt, watchos, unknown
  • 获取版本信息

    1
    QString productVersion()

部分版本信息列表:

1
2
3
4
5
6
7
8
9
10
11
12
"2016.09" (Amazon Linux AMI 2016.09)
"7.1" (Android Nougat)
"25" (Fedora 25)
"10.1" (iOS 10.1)
"10.12" (macOS Sierra)
"10.0" (tvOS 10)
"16.10" (Ubuntu 16.10)
"3.1" (watchOS 3.1)
"7 SP 1" (Windows 7 Service Pack 1)
"8.1" (Windows 8.1)
"10" (Windows 10)
"Server 2016" (Windows Server 2016)

关于更多

https://github.com/aeagean/GetOSInfo.git

关于值对象的思考

发表于 2019-09-08

使用值对象模式的好处。

  一般我们操控类内属性都是get和set方法,很常用也很好用。

1
2
3
4
5
6
7
8
9
10
class MyClass {
public:
MyClass();

void setProperty1(const QString &value);
QString getProperty1() const;

void setProperty2(const QString &value);
QString getProperty2() const;
}

  但是我们在操控类的过程中,自己不小心或第三方接口使用者误调用了set方法导致MyClass类内状态发生变化,这个是我们不想要的。

  应该对类加以限制,那么该如何限制。这时候我们可以用Builder模式,它是一个只读对象,但Builder模式使用起来比较繁琐。

  有没有更简单的只读对象呢?
答案肯定的,就是使用值对象,通过类的构造函数来设置属性。

1
2
3
4
5
6
7
8
class MyClass {
public:
MyClass(const QString &property1,
const QString &perperty2);

QString getProperty1() const;
QString getProperty2() const;
};

  上面代码我们可以看到MyClass类不再提供设置属性的方法,只提供读的方法。如果需要设置MyClass类内属性只能通过重新创建MyClass的对象方式去设置,这方法就很好地避免被它人随便修改了。

  这种方法就像是Http请求一样,无状态,用起来让人感觉踏实安心,但是它有一个致命的缺点是构造函数参数不能过多。

收集Qt支持的emoji表情-第五弹

发表于 2019-09-08

收集一些Qt富文本控件支持的emoji表情。
下列是关于符号主题的表情。

插图

使用

  • Qt版本5.12.1
  • 直接复制表情到Qt设计师的富文本框(QPlainTextEdit)就可以显示了。
  • 注意:由于下列表情会经过微信二次转换,在Qt上的实际效果如封面图。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    🔟🔢⬇️⬅️🔠🔡🔤⬆️⏬⏫
    🔽🔼🔃🔄⏪⏩ℹ️🆗🔀🔁
    🔂🆕🔝🆙🆒🆓🆖🎦📶🚻
    🚹🚺🚼🅿️♿️🚇🛄🚾🚰🚮
    🛂🛅🛃🆑🆘🆔🚫🔞📵🚯
    🚱🚳🚷🚭🚸⛔️💟🆚📳📴
    💹💱⛎🔯❎🅰️🅱️🆎🅾️💠
    ♻️🔚🔙🔛🔜💲❌❗️⭕️✖️
    ➕➖➗💮🕐🕜🕙🕥🕚🕦
    🕛🕧🕑🕝🕒🕞🕓🕟🕔🕠
    🕕🕡🕖🕢🕗🕣🕘🕤💯✔️
    ☑️🔘🔗➰🔱 ◾️◽️◼️◻️⬛️
    ⬜️✅🔲🔳⚫️⚪️🔴🔵🔷🔶
    🔹🔸🔺🔻

关于更多

  • 示例代码:
    https://github.com/aeagean/QtEmoji.git

  • Qt君公众号后台回复”Qt表情“获取更多相关内容。

收集Qt支持的emoji表情-第四弹

发表于 2019-09-08

收集一些Qt富文本控件支持的emoji表情。
下列是关于交通工具主题的表情。

插图

使用

  • Qt版本5.12.1
  • 直接复制表情到Qt设计师的富文本框(QPlainTextEdit)就可以显示了。
  • 注意:由于下列表情会经过微信二次转换,在Qt上的实际效果如封面图。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    🏠🏡🏫🏢🏣🏥🏦🏪🏩🏨
    💒⛪️🏬🏤🌇🌆🏯🏰⛺️🏭
    🗼🗾🗻🌄🌅🌠🗽🌉🎠🌈
    🎡⛲️🎢🚢🚤⛵️⛵️🚣⚓️🚀
    ✈️🚁🚂🚊🚞🚲🚡🚟🚠🚜
    🚙🚘🚗🚗🚕🚖🚛🚌🚍🚨
    🚓🚔🚒🚑🚐🚚🚋🚉🚆🚅
    🚄🚈🚝🚃🚎🎫⛽️🚦🚥⚠️
    🚧🔰🏧🎰🚏💈♨️🏁🎌🏮
    🗿🎪🎭📍🚩

关于更多

  • 示例代码:
    https://github.com/aeagean/QtEmoji.git

  • Qt君公众号后台回复”Qt表情“获取更多相关内容。

浮点数与十六进制互相转换

发表于 2019-09-07

利用强制转换类型实现。

浮点数转十六进制

  • 实现:

    1
    2
    float f = 123.45f;
    unsigned char *hex = (unsigned char *)&f;
  • 打印输出:

    1
    2
    3
    for(int i = 0; i < 4; i++) 
    printf("0x%02X ", hex[i]);
    printf("\n");

十六进制转浮点数

  • 实现:

    1
    2
    unsigned char hex[] = { 0x66, 0xE6, 0xF6, 0x42 };
    float f = *(float *)hex;
  • 打印输出:

    1
    2
    printf("%g\n", f); 
    // %g参数按浮点精度四舍五入去除多余的0.

头铁君码代码

发表于 2019-09-06

头铁君一早狂码代码,究竟是什么回事呢?

  一早看到头铁君满头大汗地敲键盘,平时最迟来的,今天却一早就在敲代码,这是怎么了?走进一看,飞快的Ctrl+C,Ctrl+V。头铁君你这是干嘛。。。手速这么快?Qt君你别说了,快给我弄一下,我的手都麻了。这烫手的山芋接不得啊。只看到它写了一堆的计算方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int add(int v1, int v2)
{
return v1 + v2;
}

float add(float v1, float v2)
{
return v1 + v2;
}

double add(double v1, double v2)
{
return v1 + v2;
}
...

  变量类型这么多靠复制粘贴到什么时候啊。头铁君虽然你很头铁也不至于这样啊。你可以使用auto和模板配合操作,让编译器给你做这些繁琐的事。
  头铁君好似明白了,立马一顿操作猛如虎,一看编译都错误!!!

1
2
3
4
auto add(auto v1, auto v2)
{
return v1 + v2;
}

头铁君啊,这里你需要注意的是:

  • 使用auto关键字的变量必须有初始值(类似于引用的使用)。
  • 函数参数和模板参数不能被声明为auto。

  auto是给编译器使用的,让编译器在编译器推断出变量的类型,而auto变量没有初始值则不能令编译器自动推断导致编译错误。

  头铁君有些不解地问,你给的方法是错误的,我还是复制粘贴去了。

  头铁君你别急,看下这个吧。

1
2
3
4
5
template<typename L, typename R>
auto add(L v1, R v2)
{
return v1 + v2;
}

  头铁君若有所思一会,立马拿起代码来验证了。

1
2
3
auto result1 = add(1, 2);
auto result2 = add(2.1, 3.1);
auto result3 = add(2, 3.0);

  一会后,头铁君果断将之前复制粘贴的代码删除了。并问,你这方法太好用了,怎么做到的?

  头铁君你看,当编译器在编译期时解析到add(1, 2)函数,会根据函数的参数类型自动创建相应的类型函数。

1
2
3
4
int add(int v1, int v2)
{
return v1 + v2;
}

  原来是这样啊。老哥这方法可以啊,但是我有一个问题就是,它的返回值是怎么确定的呢?
  就是和我们常规计算的类型方法相似咯,比如1 + 2它会根据编译器返回int类型,而1.0 + 2则会返回double类型。

  头铁君扭头不信: 这是你说的吧!

  Qt君被头铁君说得没脾气了。你可以使用typeid来验证一下。

1
2
auto result = add(2.2, 3);
std::cout << typeid(result).name();

  头铁君一看输出还真是”double“啊。


关于更多

  • Qt君公众号后台回复”头铁君“看更多头铁内容。

QByteArray转QString需要注意的一个问题

发表于 2019-09-05

QByteArray转换到QString不加注意就会转换不全的情况。

先看代码找问题

  • QString类提供Unicode字符串。
  • QByteArray类提供存放二进制数据。
    1
    2
    3
    4
    5
    6
    7
    QByteArray byteArray;
    byteArray += '1';
    byteArray += '2';
    byteArray += '\0';
    byteArray += '3';
    byteArray += '4';
    QString str(byteArray);

  看似上面代码没问题,但实际上并不能得出我们想要的结果。
  str的内容是”12”,而”\034”被剪掉了。于是找了下QString的说明文档,看到QString字符串的结尾和C风格的’\0’或0结尾相同。

Qt官方示例-QML Axes

发表于 2019-09-04

QML轴线图示例,折线图,散点图。

插图

  • 使用相同轴坐标的折线图和散点图。

插图

代码:

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
ChartView {
title: "Two Series, Common Axes"
anchors.fill: parent
legend.visible: false
antialiasing: true

ValueAxis {
id: axisX
min: 0
max: 10
tickCount: 5
}

ValueAxis {
id: axisY
min: -0.5
max: 1.5
}

LineSeries {
id: series1
axisX: axisX
axisY: axisY
}

ScatterSeries {
id: series2
axisX: axisX
axisY: axisY
}
}

/* 添加动态数据 */
Component.onCompleted: {
for (var i = 0; i <= 10; i++) {
series1.append(i, Math.random());
series2.append(i, Math.random());
}
}

  • 使用DateTimeAxis构造的图表用于显示具有日期的历史数据。

插图

代码:

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
ChartView {
title: "Accurate Historical Data"
anchors.fill: parent
legend.visible: false
antialiasing: true

LineSeries {
axisX: DateTimeAxis {
format: "yyyy MMM"
tickCount: 5
}
axisY: ValueAxis {
min: 0
max: 150
}

/* 请注意,JavaScript中的月份是以0为基础的,所以2表示3月份. */
XYPoint { x: toMsecsSinceEpoch(new Date(1950, 2, 15)); y: 5 }
XYPoint { x: toMsecsSinceEpoch(new Date(1970, 0, 1)); y: 50 }
XYPoint { x: toMsecsSinceEpoch(new Date(1987, 12, 31)); y: 102 }
XYPoint { x: toMsecsSinceEpoch(new Date(1998, 7, 1)); y: 100 }
XYPoint { x: toMsecsSinceEpoch(new Date(2012, 8, 2)); y: 110 }
}
}

/* DateTimeAxis基于QDateTimes,
* 因此我们必须将JavaScript日期转换为毫秒,
* 使它们与DateTimeAxis值匹配。
*/
function toMsecsSinceEpoch(date) {
var msecs = date.getTime();
return msecs;
}

  • 使用CategoryAxis构造的图表,使数据更易于理解。

插图

代码:

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
ChartView {
title: "Numerical Data for Dummies"
anchors.fill: parent
legend.visible: false
antialiasing: true

LineSeries {
axisY: CategoryAxis {
min: 0
max: 30
CategoryRange {
label: "critical"
endValue: 2
}
CategoryRange {
label: "low"
endValue: 4
}
CategoryRange {
label: "normal"
endValue: 7
}
CategoryRange {
label: "high"
endValue: 15
}
CategoryRange {
label: "extremely high"
endValue: 30
}
}

XYPoint { x: 0; y: 4.3 }
XYPoint { x: 1; y: 4.1 }
XYPoint { x: 2; y: 4.7 }
XYPoint { x: 3; y: 3.9 }
XYPoint { x: 4; y: 5.2 }
}
}

关于更多

  • 相关链接

    1
    https://doc.qt.io/qt-5/qtcharts-qmlaxes-example.html
  • Qt君公众号后台回复”Qt示例“获取更多内容。

Qt技巧-枚举转换遍历

发表于 2019-09-03

利用Qt元对象特性来对枚举与字符串转换和遍历。

1. QMetaEnum类

  1. QMetaEnum类提供有关枚举器的元数据。

  2. 返回与模板参数中的类型相对应的QMetaEnum。

    1
    QMetaEnum QMetaEnum::fromType()

注意: 枚举需要用Q_ENUM声明(如下例)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Object : public QObject
{
Q_OBJECT
public:
Object();
enum WeekDay {
Monday = 1,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};

Q_ENUM(WeekDay)
};

2. 枚举转字符串

  • 方法一:
    通过枚举下标获取对应字符串。

    1
    const char *key(int index) const
  • 方法二:
    通过枚举的值获取对应的字符串。

    1
    const char *valueToKey(int value) const
  • 例:

    1
    2
    3
    QMetaEnum metaEnum = QMetaEnum::fromType<Object::WeekDay>();
    const char *weekDayStr = metaEnum.valueToKey(Object::Sunday);
    qDebug() << weekDayStr;

3. 字符串转枚举

  • 可以通过ok的值来判断是否正确转换。

    1
    int keyToValue(const char *key, bool *ok = nullptr) const
  • 例:

    1
    2
    3
    4
    5
    6
    7
    QMetaEnum metaEnum = QMetaEnum::fromType<Object::WeekDay>();
    bool isOk = false;
    Object::WeekDay weekDay = (Object::WeekDay)metaEnum.keyToValue("Sunday",
    &isOk);
    if (isOk) {
    qDebug() << weekDay;
    }

4. 遍历

1
2
3
4
5
6
7
8
9
QStringList list;
QMetaEnum metaEnum = QMetaEnum::fromType<Object::WeekDay>();

for (int i = 0; i < metaEnum.keyCount(); i++) {
list += metaEnum.valueToKey(metaEnum.value(i));
// Or list += metaEnum.key(i);
}

qDebug() << list;

计算器50%+50%=0.75?

发表于 2019-09-02

打开计算器输入50% + 50%看看得出的答案。

插图

为什么答案是0.75却不是1呢?

看来50% + 50%被当成0.5的50%增长了,所以才会得出0.75。
同理100 - 100%是0也不难理解为100的100%减少。

这是特性不是bug

细想一下,如果我们将一个100元的商品降价20%,那么计算器输入100 - 20%得出80单价这是非常快的计算操作,也是符合我们对商品价格的理解。

1…789…32
Qt君

Qt君

313 日志
41 标签
© 2019 Qt君
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.4
粤ICP备 - 16070052号