1. QString字符串類(掌握)
QString是Qt的字符串類,與C++的string相比,不再使用ASCII編碼,QString使用的是Unicode編碼。
QString中每個字符都是一個16位的QChar,而不是8位的char。
QString完全支持中文,但是由于不同的技術可能會采用不同的中文編碼, 也有可能會遇到中文編碼一致性的問題。
從此亂碼是路人
Qt中對C++的類重寫時,充分考慮到了C++程序員的編程習慣,因此QString幾乎支持所有string的API,除此之外也會增加一些額外的函數。
// int → QString
// 參數1:要轉換的原始數據
// 參數2:進制
// 返回值:轉換后的新的QString對象
QString QString::?number(int n, int base = 10)[static]
// QString -> int
// 參數1:轉換成功還是失敗,成功參數設置為true、失敗設置為false
// 參數2:進制
// 返回值:轉換后的int數據,轉換失敗返回0
int QString::?toInt(bool * ok = 0, int base = 10) const
dialog.h
#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this); QString str = "?????.";
qDebug() << str; ui->textBrowser->append(str); // int → QString
int a = 255;
str = QString::number(a);
qDebug() << str; // "255"
str = QString::number(a,2);//二進制
qDebug() << str; // "11111111" str = QString::number(a,16);
qDebug() << str; // "ff" // QString -> int
bool result = false;
str = "0";
qDebug() << str.toInt(&result); // 0
qDebug() << result; // true str = "你好";
qDebug() << str.toInt(&result); // 0
qDebug() << result; // false
}Dialog::~Dialog()
{
delete ui;
}
舉例
QString str1 = "0"; // 合法的數字0
QString str2 = "你好"; // 非數字字符串
QString str3 = "123"; // 合法數字bool ok1, ok2, ok3;int num1 = str1.toInt(&ok1); // 轉換成功,num1=0, ok1=true
int num2 = str2.toInt(&ok2); // 轉換失敗,num2=0, ok2=false
int num3 = str3.toInt(&ok3); // 轉換成功,num3=123, ok3=trueqDebug() << "str1:" << num1 << ok1; // 輸出: 0 true
qDebug() << "str2:" << num2 << ok2; // 輸出: 0 false
qDebug() << "str3:" << num3 << ok3; // 輸出: 123 true
當使用 toInt() 轉換用戶輸入或外部數據時,必須檢查 ok 參數:
QString userInput = ui->lineEdit->text();
bool ok;
int value = userInput.toInt(&ok);if (ok) {
// 轉換成功,使用value
qDebug() << "輸入的是有效整數:" << value;
} else {
// 轉換失敗,處理錯誤
qDebug() << "輸入不是有效整數";
QMessageBox::warning(this, "錯誤", "請輸入有效的整數");
}
不建議死記QString的API,因為數量多且都有示例代碼,只需要把常用的關鍵詞記住即可:
2. 容器類(掌握)
Qt重寫了C++的STL中的容器類,相比較于C++的容器類,Qt的容器類更輕巧、更安全、更加的易于使用。因為Qt的容器類進行了速度和存儲的優化,減少了可執行文件的生成體積,幾乎全面兼容STL容器類API接口,線程是安全的,可以被多個線程所訪問。
2.1 順序容器—QList類
本次課程內容使用QList類存儲Student元素,Student是自定義類型。在Qt項目中創建一個C++類的操作步驟如下:
- 在Qt Creator中,選中項目名稱,鼠標右鍵點擊添加新文件。
- 在彈出的窗口中按照下圖所示,進行操作
3.在彈出的窗口中輸入類名(大駝峰/帕斯卡)
4.在項目管理界面直接點擊完成,可以看到新的文件已經創建成功。
student.h
#ifndef STUDENT_H
#define STUDENT_H#include <QString>
class Student
{
public:
Student(int,QString,QString);
~Student(); int getId() const;
void setId(int value); QString getName() const;
void setName(const QString &value); QString getMajor() const;
void setMajor(const QString &value);private:
int id; // 編號
QString name; // 姓名
QString major; // 專業};#endif // STUDENT_H
student.cpp
#include "student.h"Student::Student(int id, QString name, QString major):id(id)
{
this->name = name;//兩種寫法
this->major = major;
}Student::~Student()
{}
int Student::getId() const
{
return id;
}void Student::setId(int value)
{
id = value;
}
QString Student::getName() const
{
return name;
}void Student::setName(const QString &value)
{
name = value;
}
QString Student::getMajor() const
{
return major;
}void Student::setMajor(const QString &value)
{
major = value;
}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QDebug>
#include "student.h"namespace Ui {
class Dialog;
}class Dialog : public QDialog
{
Q_OBJECTpublic:
explicit Dialog(QWidget *parent = 0);
~Dialog();private:
Ui::Dialog *ui;
};#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
// 創建QList對象
QList<Student> lis;
Student s1(1,"志浩","開挖掘機");
Student s2(2,"云龍","開意大利炮");
Student s3(3,"雨龍","美容美發");
Student s4(4,"文博","算命的");
Student s5(5,"昌文","開挖掘機炒菜"); // 向后插入元素(鏈式調用)
lis << s1 << s2 << s3 << s4; // 插入
lis.insert(1,s5); // 在第二個位置上插入s5 // 刪除元素
lis.removeFirst(); // 刪除第一個元素 lis.removeLast(); // 刪除最后一個元素 // 編譯報錯,不支持只定義類型比較,如果想要實現此功能,需要將==運算符重載
// lis.removeOne(s3); // 刪除所有相同元素的第一個元素 // lis.removeAll(s3); // 刪除所有相同元素 lis.removeAt(1); // 刪除第二個元素 // 普通遍歷
for(int i = 0; i < lis.count(); i++)
{
// at函數在qt中執行效率比[] 高
// 只能在右值使用
Student s = lis.at(i);
qDebug() << s.getId() << s.getName() << s.getMajor();
} // C++迭代器遍歷
for(QList<Student>::iterator iter = lis.begin(); iter != lis.end(); iter++)
{
Student s = *iter;
qDebug() << s.getId() << s.getName() << s.getMajor();
}
}Dialog::~Dialog()
{
delete ui;
}
2.2 關聯容器—QMap類
重新實現了STL中的map類,QMap也兼容了map類的大部分API,也增加了一些自己的API。
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this); // 創建一個棧內存對象***
QMap<QString,QString>map; // 插入數據
map.insert("姓名","旭杰");
map.insert("年齡","18");
map.insert("地址","同住地球村");
map.insert("專業","物聯網");
map.insert("愛好","睡覺"); // 如果容器內的元素支持qDebug輸出,則容器給本身也支持輸出
qDebug() << map;//打印所有鍵值對 // 刪除
qDebug() << map.remove("專業"); // 1 返回的是刪除的鍵值對的數量
qDebug() << map.remove("專業"); // 0 沒有了 // 判斷某個鍵值對是否存在
if(map.contains("籍貫"))
{
map["籍貫"] = "山東省";
} qDebug() << map; qDebug() << map.value("愛好","沒有 沒有"); // "睡覺"
qDebug() << map.value("喜好","沒有 沒有"); // "沒有 沒有" // C++迭代器遍歷
for(QMap<QString,QString>::iterator i = map.begin();i != map.end();i++)
{
// 輸出鍵值對
qDebug() << i.key() << i.value();
}}Dialog::~Dialog()
{
delete ui;
}
3. Qt數據類型(掌握)
3.1 跨平臺數據類型
Qt是一個跨平臺的開發框架,所以必須保證各個平臺的數據類型的長度保持一致,因此Qt為常見的基本類型定義了新的類型符號。
在Qt的環境下,可以直接使用。
3.2 QVariant統一變量類
QVariant類型可以與Qt常見的數據類型完成相互的轉換,因此此類型的函數具有類似多態的特點。
使用QVariant類型完成數據類型轉換:
qint64 a = 123;
QVariant v(a);
QString str = v.toString(); // 將qint64數據轉換為QStringqDebug() << str; // "123" v = str;int b = v.toInt(); // 轉換為intqDebug() << b; // 123
4. 時間與日期處理(掌握)
Qt中使用QDate類處理日期,使用QTime處理時間,使用QDateTime處理時間和日期。以QDateTime為例進行講解。
需要注意的是,QDateTime的數據來自于系統時間,所以修改系統時間會影響到QDateTime的數據。
常用函數:
// 返回自1970年1月1日00:00:00到現在的毫秒數
qint64 QDateTime::?currentMSecsSinceEpoch()[static]
- 時間戳的作用,計算代碼的運算時間。
qint64 start = QDateTime::currentMSecsSinceEpoch();
ui->setupUi(this);qDebug() << QDateTime::currentMSecsSinceEpoch() - start;
?????2. 時間戳的其他作用
可以使用時間戳作為隨機數的種子。但是需要注意,計算機中都是偽隨機。不是真正的隨機數,計算機無法做到真正的隨機數。
獲取當前的時間和日期對象。
// 返回一個包含當前日期和時間的QDateTime的對象
QDateTime QDateTime::?currentDateTime()[static]
// 格式化輸出年月日、時分秒
QString QDateTime::?toString(const QString & format) const
秒:ss
#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
qint64 start = QDateTime::currentMSecsSinceEpoch();
ui->setupUi(this);
qDebug() << QDateTime::currentMSecsSinceEpoch() - start; // 使用時間戳作為隨機數的種子
qsrand(start); // 生成隨機數(生成101以內的隨機數)
qDebug() << qrand() % 101; QDateTime dt = QDateTime::currentDateTime();
qDebug() << dt.toString("yyyy年MMMM月dddd日 hh時mm分ss秒");
}Dialog::~Dialog()
{
delete ui;
}
其他與日期和時間相關的組件:
5. QTimer定時器(重點)
QTimer類可以實現一個延時任務或者周期任務。
延時任務:微波爐定時功能
周期任務:鬧鐘,每天都響
使用定時器需要包含頭文件#include<QTimer>,定時器繼承自QObject。
常用屬性:
- interval : int
時間間隔,單位毫秒。
- singleShot : bool
是否為一次性。true為延時任務、false為周期任務。
- active : const bool
當前定時器的運行狀態
// 構造函數,堆區開辟
QTimer:: QTimer(QObject * parent = 0)
QLCDNumber 組件
顯示出10:30:32 這樣的時間
因為顯示時間需要8位,所以需要將此屬性改為8
// lcdNuber的顯式函數
void display(const QString & s)[slot]
// 定時器觸發時,發射的信號
void QTimer:: timeout()[signal]
dialog.h
#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QTimer>
#include <QDateTime>namespace Ui {
class Dialog;
}class Dialog : public QDialog
{
Q_OBJECTpublic:explicit Dialog(QWidget *parent = 0);~Dialog();private:
Ui::Dialog *ui;private:
QTimer *timer;private slots:void timeoutSlot();
};#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this); timer = new QTimer(this); // 提前刷新
timeoutSlot();//不提前刷新會先顯示原來的0,再顯示時間 // 設置時間間隔
timer->setInterval(500); // 設置為周期任務(默認就是周期任務)
timer->setSingleShot(false); connect(timer,SIGNAL(timeout()),
this,SLOT(timeoutSlot())); // 啟動定時器
timer->start();
}Dialog::~Dialog()
{
if(timer->isActive()) // 如果正在運行,則先關閉
{
timer->stop(); // 關閉定時器
} delete timer;
delete ui;
}void Dialog::timeoutSlot()
{
// 獲取當前時間,轉換:時:分:秒格式的QString字符串
QString str = QDateTime::currentDateTime().toString("hh:mm:ss");
ui->lcdNumber->display(str);
}