Qt Creator Tool Overview and Usage
When creating a project using Qt, you're essentially establishing a window class where you can incorporate various components such as labels, buttons, and other UI elements. After project creation, several key files are generated:
| File | Purpose |
|---|---|
| widget.h | Creates the window class where label classes, button classes, and other UI components can be added |
| widget.cpp | Handles initialization of various classes including positioning, sizing, signals, and slot functions |
| main.cpp | Entry point of the entire project, launches the application and calls other files to run the window program |
First Qt Application Example
(1) Modify the "main.cpp" file.
#include "windowwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
WindowWidget win; // Create a window instance
win.resize(600, 400); // Set window dimensions
win.setWindowTitle("My First Qt Application"); // Configure window title
win.show();
return app.exec();
}
(2) Update the "windowwidget.h" file.
#ifndef WINDOWWIDGET_H
#define WINDOWWIDGET_H
#include <QWidget>
#include <QLabel>
class WindowWidget : public QWidget
{
Q_OBJECT
public:
WindowWidget(QWidget *parent = nullptr);
~WindowWidget();
private:
// QLabel *labelDisplay = new QLabel("Qt Programming", this); // Avoid direct initialization in header
QLabel *labelDisplay;
};
#endif // WINDOWWIDGET_H
(3) Adjust the "windowwidget.cpp" file.
#include "windowwidget.h"
WindowWidget::WindowWidget(QWidget *parent)
: QWidget(parent)
{
labelDisplay = new QLabel("Qt Programming", this); // Initialize label in .cpp file
labelDisplay->setGeometry(60, 60, 300, 120); // Position and size the label
labelDisplay->setStyleSheet("QLabel{background-color:blue;color:white}"); // Styling
labelDisplay->setFont(QFont("Arial", 20)); // Font settings
}
WindowWidget::~WindowWidget()
{
}
(4) Execute the program.
Qt Signal-Slot Mechanism
Signal: Notification emitted under specific conditions.
Slot: Function that responds to signals.
The connection between signals and slots is implemented using the QObject::connect() function.
Signal-Slot Parameters
[static] QMetaObject::Connection QObject::connect(const QObject *emitter, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
| Parameter 1 (emitter) | Object emitting the signal | | Parameter 2 (signal) | Signal from the emitter object | | Parameter 3 (receiver) | Signal recipient | | Parameter 4 (method) | Slot function of receiver object, called when emitter's signal is detected |
Connection Patterns
(1) One signal connected to another signal:
connect(obj1, SIGNAL(signal1), obj2, SIGNAL(signal2));
(2) One signal connected to multiple slots:
connect(obj1, SIGNAL(signal1), obj2, SLOT(slot2));
connect(obj1, SIGNAL(signal1), obj3, SLOT(slot3));
(3) Multiple signals connected to the same slot:
connect(obj1, SIGNAL(signal1), obj2, SLOT(slot2));
connect(obj3, SIGNAL(signal3), obj2, SLOT(slot2));
(4) Standard connection pattern:
connect(obj1, SIGNAL(signal1), obj2, SLOT(slot2));
Signal-Slot Advantages
(1) Loose coupling: Signals and slots don't need to know who uses them or who they're used by, reducing coupling and making programs more stable.
(2) Type compatibility: Connection parameters must match. A class supporting signals and slots must inherit from QObject or its subclasses. Qt's signal-slot mechanism doesn't support templates.
Performance Considerations
While enhancing communication flexibility between objects, performance may be impacted. Calling a slot through signal emission runs slower than direct non-virtual function calls due to:
- Signal queuing in multi-threaded environments
- Parameter marshaling/unmarshaling
- Safe traversal of all connections
- Locating receiving objects
Sphere Volume Calculation Example
(1) Create a new project
(2) Modify "main.cpp" file.
#include "calcdialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
CalcDialog dialog;
dialog.setWindowTitle("Sphere Volume Calculator");
dialog.show();
return app.exec();
}
(3) Update "calcdialog.h" file.
#ifndef CALCDIALOG_H
#define CALCDIALOG_H
#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
class CalcDialog : public QDialog
{
Q_OBJECT
public:
CalcDialog(QWidget *parent = nullptr);
~CalcDialog();
private:
QLabel *radiusLabel, *resultLabel;
QLineEdit *radiusInput;
QPushButton *calculateButton;
private slots:
void calculateSphereVolume(); // Slot function for volume calculation
};
#endif // CALCDIALOG_H
(4) Modify "calcdialog.cpp" file.
#include "calcdialog.h"
#include <QGridLayout>
const static double PI_VALUE = 3.14159;
CalcDialog::CalcDialog(QWidget *parent)
: QDialog(parent)
{
radiusLabel = new QLabel(this);
radiusLabel->setText(tr("Enter sphere radius:"));
resultLabel = new QLabel(this);
radiusInput = new QLineEdit(this);
calculateButton = new QPushButton(this);
calculateButton->setText(tr("Calculate Volume"));
QGridLayout *layoutGrid = new QGridLayout(this);
layoutGrid->addWidget(radiusLabel, 0, 0);
layoutGrid->addWidget(radiusInput, 0, 1);
layoutGrid->addWidget(resultLabel, 1, 0);
layoutGrid->addWidget(calculateButton, 1, 1);
connect(calculateButton, SIGNAL(clicked()), this, SLOT(calculateSphereVolume()));
}
CalcDialog::~CalcDialog()
{
}
void CalcDialog::calculateSphereVolume()
{
bool conversionSuccess;
QString displayText;
QString inputRadius = radiusInput->text();
int radiusValue = inputRadius.toInt(&conversionSuccess);
double volumeResult = 4.0/3.0 * PI_VALUE * radiusValue * radiusValue * radiusValue;
resultLabel->setText(displayText.setNum(volumeResult));
}
String Classes and Common Data Types
Qt String Operations
Create a Qt Console Application.
String Concatenation with "+"
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString firstStr = "Welcome to ";
firstStr = firstStr + "Qt Development";
qDebug() << firstStr;
qDebug() << qPrintable(firstStr);
QString secondStr = "54321";
secondStr += "VWXYZ";
qDebug() << secondStr;
return app.exec();
}
Using "QString::append" for Concatenation
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString greeting = "Good";
QString farewell = "morning";
greeting.append(farewell);
qDebug() << qPrintable(greeting);
greeting.append("Hello Universe!");
qDebug() << qPrintable(greeting);
return app.exec();
}
"QString::asprintf()" String Formatting
For C++17:
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString tempString;
tempString = QString::asprintf("%s", "Greeting ");
qDebug() << qPrintable(tempString);
tempString = QString::asprintf("%s", "Greeting Universe!");
qDebug() << qPrintable(tempString);
tempString = QString::asprintf("%s %s", "Welcome", "here.");
qDebug() << qPrintable(tempString);
}
For C++11:
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString tempString;
tempString.sprintf("%s", "Greeting ");
qDebug() << qPrintable(tempString);
tempString.sprintf("%s", "Greeting Universe!");
qDebug() << qPrintable(tempString);
tempString.sprintf("%s %s", "Welcome", "here.");
qDebug() << qPrintable(tempString);
return app.exec();
}
"QString::arg()" String Formatting
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString tempString;
tempString = QString("%1 was born in %2.").arg("Alice").arg(2001);
qDebug() << tempString;
return app.exec();
}
"QString::insert()" Function
Inserts text at a specified position.
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString digit = "five";
QString memory = "Memory is ten seconds story";
memory.insert(7, digit);
qDebug() << memory;
// Result: Memory is five ten seconds story
return app.exec();
}
"QString::prepend()" Function
Prepends text to the beginning of the source string.
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString subject = "Cat";
QString story = " has a ten minute memory";
story.prepend(subject);
qDebug() << story;
return app.exec();
}
"QString::replace()" Function
Replaces specified content in the source string.
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString memory = "Cat has a ten minute memory";
memory.replace("ten", "twenty");
qDebug() << memory;
return app.exec();
}
"QString::startsWith()" Function
Checks if a string begins with a specific substring.
Qt::CaseInsensitive means case-insensitive; Qt::CaseSensitive means case-sensitive; Counterpart: QString::endsWith().
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString testString = "What is your name?";
qDebug() << testString.startsWith("What", Qt::CaseSensitive); // true
qDebug() << testString.startsWith("whAT", Qt::CaseSensitive); // false
qDebug() << testString.startsWith("whAT", Qt::CaseInsensitive); // true
qDebug() << testString.startsWith("name", Qt::CaseSensitive); // false
return app.exec();
}
"QString::contains()" Function
Checks if a specified substring exists within a string.
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString testString = "What is your name?";
qDebug() << testString.contains("your", Qt::CaseSensitive); // true
qDebug() << testString.contains("what", Qt::CaseInsensitive); // false
return app.exec();
}
"QString::toInt()" Function
Similar functions exist: "QString::toDouble()" function "QString::toFloat()" function "QString::toLong()" function
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString numberStr = "42";
bool success;
int hexValue = numberStr.toInt(&success, 16);
qDebug() << "success=" << success << "," << "hex=" << hexValue << Qt::endl;
return app.exec();
}
"QString::compare()" Function
#include <QCoreApplication>
#include <QDebug>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
int comparison1 = QString::compare("hello", "HELLO", Qt::CaseInsensitive);
int comparison2 = QString::compare("about", "Dog", Qt::CaseSensitive);
int comparison3 = QString::compare("hello", "Dog", Qt::CaseInsensitive);
cout << "comparison1=" << comparison1 << "," << "comparison2=" << comparison2 << "," << "comparison3=" << comparison3 << endl;
return app.exec();
}
Converting QString to ASCII Codes
#include <QCoreApplication>
#include <QDebug>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString text = "XYZ xyz";
QByteArray byteData = text.toUtf8();
for (int i = 0; i < text.size(); i++)
qDebug() << int(byteData.at(i));
return app.exec();
}
Common Qt Basic Data Types (defined in #include<QtGlobal>)
Data Types
| Type Name | Description | Notes |
|---|---|---|
| qint8 | signed char | 8-bit signed integer |
| qint16 | signed short | 16-bit signed integer |
| qint32 | signedd int | 32-bit signed integer |
| qint64 | long long int or (_int64) | 64-bit signed integer, defined as _int64 on Windows |
| qintptr | qint32 or qint64 | Pointer type varies by system, qint32 on 32-bit, qint64 on 64-bit |
| qlonglong | long long int or (_int64) | Defined as _int64 on Windows |
| qptrdiff | qint32 or qint64 | Varies by system, qint32 on 32-bit, qint64 on 64-bit |
| qreal | double or float | Defaults to double unless configured with -qreal float |
| quint8 | unsigned char | 8-bit unsigned integer |
| quint16 | unsigned shortt | 16-bit unsigned integer |
| quint32 | unsigned int | 32-bit unsigned integer |
| quint64 | unsigned long long int or (unsigned _int64) | 64-bit unsigned integer, defined as unsigned_int64 on Windows |
| quintptr | quint32 or quint64 | Varies by system, quint32 on 32-bit, quint64 on 64-bit |
| qulonglong | unsigned long long int or (unsigned _int64) | Defined as _int64 on Windows |
| uchar | unsigned char | Unsigned character type |
| uint | unsigned int | Unsigned integer |
| ulong | unsigned long | Unsigned long integer |
| ushort | unsigned short | Unsigned short integer |
QDateTime & QByteArray
#include <QCoreApplication>
#include <QDebug>
#include <iostream>
#include <QDateTime>
using namespace std;
int main(int argc, char *argv[])
{
QDateTime dateTime;
QString dateString = dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
qDebug() << dateString << Qt::endl;
QByteArray original("Qt Development Sample Text.");
QByteArray lowercase = original.toLower();
qDebug() << lowercase << Qt::endl;
QByteArray uppercase = original.toUpper();
qDebug() << uppercase << Qt::endl;
return app.exec();
}
QMap, QHash, QVector
QMap Class
QMap<Key,T> provides a mapping from keys of type Key to values of type T. Typically, QMap stores data as one key per value, storing data in key order. For one-key-multiple-values scenarios, QMap provides QMap<Key,T>::insertMulti() and QMap<Key,T>::values() functions. QMultiMap class instantiates a QMap object.
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// QMap example
QMap<QString, int> mapExample;
mapExample["Literature"] = 115;
mapExample["History"] = 125;
mapExample.insert("Geography", 110);
mapExample.insert("Biology", 95);
mapExample.insert("Art", 105);
qDebug() << mapExample << Qt::endl;
mapExample.remove("Art");
qDebug() << mapExample << Qt::endl;
// Iterating through QMap
QMapIterator<QString, int> iterator(mapExample);
while(iterator.hasNext())
{
iterator.next();
qDebug() << iterator.key() << ":" << iterator.value();
}
// STL-style iteration
QMap<QString, int>::const_iterator stlIter = mapExample.constBegin();
while(stlIter != mapExample.constEnd())
{
qDebug() << stlIter.key() << ":" << stlIter.value();
stlIter++;
}
// Lookup operations
qDebug() << Qt::endl;
qDebug() << "key-->value:" << mapExample.value("Geography");
qDebug() << "value-->key:" << mapExample.key(95) << Qt::endl;
// Update value
mapExample.insert("Geography", 118);
qDebug() << mapExample.value("Geography");
// Check existence
qDebug() << "result=" << mapExample.contains("Literature");
qDebug() << "result=" << mapExample.contains("Art");
// Get all keys and values
qDebug() << Qt::endl;
QList<QString> keys = mapExample.keys();
qDebug() << keys;
QList<int> values = mapExample.values();
qDebug() << values;
// One key to multiple values
QMultiMap<QString, QString> multiMap;
multiMap.insert("student", "id");
multiMap.insert("student", "name");
multiMap.insert("student", "gender");
multiMap.insert("student", "age");
multiMap.insert("student", "height");
multiMap.insert("student", "weight");
qDebug() << multiMap;
return app.exec();
}
QHash Class
QHash<Key,T> has nearly identical API to QMap. QHash maintains a hash table that adapts to the number of items.
QHash organizes data in arbitrary order. When storage order doesn't matter, QHash is recommended for data containers.
Differences between QMap and QHash:
(1) QHash and QMap have similar functionality, but QHash offers faster lookup speeds; (2) QMap stores data in key order, while QHash stores in arbitrary order; (3) QMap keys must provide "<" operator, while QHash keys must provide "==" operator and a global qHash() function.
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// QHash example
QHash<QString, int> hashExample;
hashExample["item 1"] = 5;
hashExample["item 1"] = 10;
hashExample["item 4"] = 6;
hashExample["item 2"] = 4;
hashExample.insert("item 3", 40);
QList<QString> keyList = hashExample.keys();
for(int i = 0; i < keyList.length(); i++)
qDebug() << keyList[i] << "," << hashExample.value(keyList[i]);
// QHash iterator
qDebug() << Qt::endl;
QHash<QString, int> hashContainer;
hashContainer["item 1"] = 35;
hashContainer["item 2"] = 45;
hashContainer["item 3"] = 55;
hashContainer["item 4"] = 65;
hashContainer.insert("item 3", 110);
QHash<QString, int>::const_iterator hashIter;
for(hashIter = hashContainer.begin(); hashIter != hashContainer.end(); hashIter++)
qDebug() << hashIter.key() << "-->" << hashIter.value();
// Existence check
qDebug() << "result=" << hashContainer.contains("item 4");
// Remove item
hashContainer.remove("item 4");
for(hashIter = hashContainer.begin(); hashIter != hashContainer.end(); hashIter++)
qDebug() << hashIter.key() << "-->" << hashIter.value();
return app.exec();
}
QVector Class
QVector<T> stores a sequence of values of type T in adjacent memory locations. Insertion operations at the front or middle of a QVector are slow because they require moving large amounts of data due to how QVector stores data.
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// QVector example
QVector<int> vectorExample;
// First assignment method
vectorExample << 15;
vectorExample << 25;
vectorExample << 35;
vectorExample << 45;
// Second assignment method
vectorExample.append(55);
vectorExample.append(65);
vectorExample.append(75);
vectorExample.append(85);
vectorExample.append(105);
vectorExample.append(95);
qDebug() << vectorExample << Qt::endl;
// Count elements
qDebug() << "vector count=" << vectorExample.count() << Qt::endl;
// Iterate through elements
for(int i = 0; i < vectorExample.count(); i++)
qDebug() << vectorExample[i];
// Remove elements
qDebug() << Qt::endl;
vectorExample.remove(0); // Remove first element
for(int i = 0; i < vectorExample.count(); i++)
qDebug() << vectorExample[i];
qDebug() << Qt::endl;
vectorExample.remove(2, 3); // Remove 3 elements starting from index 2
for(int i = 0; i < vectorExample.count(); i++)
qDebug() << vectorExample[i];
// Check containment
qDebug() << Qt::endl;
qDebug() << "result:" << vectorExample.contains(95) << Qt::endl;
qDebug() << "result:" << vectorExample.contains(650) << Qt::endl;
return app.exec();
}
QList Class & QLinkedList Class
QList Class
QList<T> employs different storage strategies based on data types:
(1) If T is a pointer type or basic type with pointer-size bytes, QList<T> stores values directly in its array.
(2) If QList<T> stores pointers to objects, the pointers reference the actual objects.
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// QList example
QList<int> listExample; // Initialize empty QList<int>
for(int i = 0; i < 10; i++)
listExample.insert(listExample.end(), i + 15);
qDebug() << listExample;
// Read-write iterator
QList<int>::iterator iter;
qDebug() << Qt::endl;
qDebug() << "Result1:";
for(iter = listExample.begin(); iter != listExample.end(); iter++)
{
qDebug() << (*iter);
*iter = (*iter) * 10 + 8;
}
// Read-only iterator
qDebug() << Qt::endl;
qDebug() << "Result1:";
QList<int>::const_iterator constIter;
for(constIter = listExample.constBegin(); constIter != listExample.constEnd(); constIter++)
qDebug() << *constIter;
// Add elements
listExample.append(777);
QList<int>::iterator iter1;
qDebug() << Qt::endl;
qDebug() << "Result2:";
for(iter1 = listExample.begin(); iter1 != listExample.end(); iter1++)
qDebug() << *iter1;
// Find elements
qDebug() << Qt::endl;
qDebug() << "Result3:";
qDebug() << listExample.at(3);
qDebug() << listExample.contains(88);
qDebug() << listExample.contains(188);
// Modify elements
qDebug() << Qt::endl;
qDebug() << "Result4:";
listExample.replace(5, 999);
qDebug() << listExample;
// Remove elements
qDebug() << Qt::endl;
qDebug() << "Result5:";
listExample.removeAt(0);
listExample.removeFirst();
listExample.removeAt(6);
qDebug() << listExample;
return app.exec();
}
QLinkedList Class
In Qt6, QLinkedList class usage workaround:
QLinkedList<T> is a linked list that stores data in non-contiguous memory blocks. QLinkedList<T> cannot use indexing, only iterators for data access. Compared to QList, QLinkedList offers higher efficiency when inserting into large lists.
QLinkedList class cannot access elements by index. For large-scale data storage, QLinkedList is recommended (fast, efficient insertion and deletion).
#include <QCoreApplication>
#include <QDebug>
#include <QLinkedList>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// QLinkedList example
QLinkedList<QString> monthList;
for(int i = 1; i <= 12; i++)
monthList << QString("%1%2").arg("Month: ").arg(i);
// Read-write iterator
qDebug() << "Result1:";
QLinkedList<QString>::iterator writeIter = monthList.begin();
for(; writeIter != monthList.end(); writeIter++)
qDebug() << *writeIter;
// Read-only iterator
qDebug() << Qt::endl << "Result2:";
QLinkedList<QString>::const_iterator readIter = monthList.constBegin();
for(; readIter != monthList.end(); readIter++)
qDebug() << *readIter;
return app.exec();
}
STL-Style Iterator Container Traversal
| Container Class | Read-Only Iterator | Read-Write Iterator |
|---|---|---|
| QList<T>, QQueue<T> | QList<T>::const_iterator | QList<T>::iterator |
| QLinkedList<T> | QLinkedList<T>::const_iterator | QLinkedList<T>::iterator |
QVariant Class Applications
QVariant class is essentially a C++ union data type that can store many Qt type values, including QBrush, QColor, QString, etc. It can also store Qt container type values.
QVariant::StringList is an enum variable defined by Qt for QVariant::type. Other common enum variables include:
| Variable | Corresponding Type | Variable | Corresponding Type |
|---|---|---|---|
| QVariant::Invalid | Invalid type | QVariant::Time | QTime |
| QVariant::Region | QRegion | QVariant::Line | QLine |
| QVariant::Bitmap | QBitmap | QVariant::Palette | QPalette |
| QVariant::Bool | bool | QVariant::List | QList |
| QVariant::Brush | QBrush | QVariant::SizePolicy | QSizePolicy |
| QVariant::Size | QSize | QVariant::String | QString |
| QVariant::Char | QChar | QVariant::Map | QMap |
| QVariant::Color | QColor | QVariant::StringList | QStringList |
| QVariant::Cursor | QCursor | QVariant::Point | QPoint |
| QVariant::Date | QDate | QVariant::Pen | QPen |
| QVariant::DateTime | QDateTime | QVariant::Pixmap | QPixmap |
| QVariant::Double | double | QVariant::Rect | QRect |
| QVariant::Font | QFont | QVariant::Image | QImage |
| QVariant::Icon | QIcon | QVariant::UserType | User-defined type |
Example:
(1) Create MainWindow project;
(2) Modify "main.cpp" file;
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
return app.exec();
}
(3) Modify "mainwindow.h" file;
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
// Define student structure
struct Student
{
int id;
QString name;
int grade;
};
Q_DECLARE_METATYPE(Student)
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
};
#endif // MAINWINDOW_H
(4) Modify "mainwindow.cpp" file
#include "mainwindow.h"
#include <QVariant>
#include <QDebug>
#include <QColor>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QVariant var1(398);
qDebug() << "var1:" << var1.toInt();
QVariant var2("shanghai");
qDebug() << "var2:" << var2.toString();
QMap<QString, QVariant> mapExample;
qDebug() << Qt::endl;
mapExample["integer"] = 3000;
mapExample["decimal"] = 109.98;
mapExample["text"] = "excellent";
mapExample["color"] = QColor(255, 0, 255); // QColor type
// Output and conversion
qDebug() << mapExample["integer"] << mapExample["integer"].toInt();
qDebug() << mapExample["decimal"] << mapExample["decimal"].toDouble();
qDebug() << mapExample["text"] << mapExample["text"].toString();
qDebug() << mapExample["color"] << mapExample["color"].value<QColor>();
// Create string list: QStringList
qDebug() << Qt::endl;
QStringList stringList;
stringList << "X" << "Y" << "Z" << "W" << "V" << "U";
QVariant listVar(stringList); // Store list in QVariant variable
if(listVar.type() == QVariant::StringList)
{
QStringList retrievedList = listVar.toStringList();
for(int i = 0; i < retrievedList.size(); i++)
{
qDebug() << retrievedList.at(i); // Output list data
}
}
// Structure and QVariant combination
qDebug() << Qt::endl;
Student studentInfo;
studentInfo.id = 202408;
studentInfo.name = "alice";
studentInfo.grade = 825;
// Use static method for storage
QVariant studentVar = QVariant::fromValue(studentInfo);
if(studentVar.canConvert<Student>()) // Check convertibility
{
Student temp = studentVar.value<Student>(); // Retrieve data
Student converted = qvariant_cast<Student>(studentVar); // Retrieve data alternative
qDebug() << "student:id=" << temp.id << ",name=" << temp.name << ",grade=" << temp.grade;
qDebug() << "student:id=" << converted.id << ",name=" << converted.name << ",grade=" << converted.grade;
}
}
MainWindow::~MainWindow()
{
}
Common Algorithms and Regular Expressions
Common Algorithms
(1) double c = qAbs(a): qAbs() returns absolute value of double a; (2) double max = qMax(b,c): qMax() returns maximum of two values; (3) int bn = qRound(b): Returns closest integer to floating-point number (rounding); (4) int cn = qSwap(bn,cn): Swaps values of two numbers;
Example:
(1) Create widget project;
(2) Modify "widget.cpp" file;
#include "widget.h"
#include <QtGlobal>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
double num1 = -88.754, num2 = 35.88;
double absResult = qAbs(num1); // Absolute value
qDebug() << "num1=" << absResult;
double maxResult = qMax(num1, num2); // Maximum value
qDebug() << "maxResult" << maxResult;
int rounded1 = qRound(num2); // Rounding
qDebug() << "rounded1=" << rounded1;
int rounded2 = qRound(num1); // Rounding
qDebug() << "rounded2=" << rounded2;
qSwap(num1, num2); // Swap values
qDebug() << num1 << "," << num2 << Qt::endl;
}
Widget::~Widget()
{
}
Regular Expressions
Regular expressions, also known as pattern expressions (Regular Expression, abbreviated as regex, regexp, or RE in code), are text patterns containing ordinary characters (such as letters from a to z) and special characters (called "metacharacters"). Regular expressions use single strings to describe, match sequences of strings that follow certain grammatical rules, typically used for searching and replacing text that matches specific patterns. Regular expressions describe string matching patterns that can check if a string contains certain substrings, replace matched substrings, or extract substrings meeting specific criteria.
Regular expressions consist of expressions, quantifiers, and assertions.
(1) The simplest expression is a character. Character sets can use expressions like "[AEIOU]", matching all uppercase vowels; using "[^AEIOU]" matches all non-vowel letters, i.e., consonants; consecutive character sets can use expressions like "[a-z]", matching all lowercase English letters.
(2) Quantifiers specify occurrence counts of expresions, such as "x[1,2]" meaning "x" can appear at least once, at most twice.
Quantifiers in Regular Expressions:
| Quantifier | Meaning | Quantifier | Meaning |
|---|---|---|---|
| E? | Matches 0 or 1 time | E{n,} | Matches at least n times |
| E+ | Matches 1 or more times | E{,m} | Matches at most m times |
| E* | Matches 0 or more times | E{n,m} | Matches at least n, at most m times |
| E{n} | Matches n times |
Assertions in Regular Expressions:
| Symbol | Meaning | Symbol | Meaning |
|---|---|---|---|
| ^ | Matches at string start | \B | Non-word boundary |
| $ | Matches at string end | (?=E) | Matches only if followed by E |
| \b | Word boundary | (?!E) | Matches only if not followed by E |
Example:
(1) Create mainwindow project;
(2) Modify "mainwindow.cpp" file;
#include "mainwindow.h"
#include <QDebug>
#include <regex>
#include <QString>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
/*
* Match phone numbers via regular expression
* 11 digits with different encoding patterns
* First 3: Network identification (China Mobile, China Unicom, China Telecom)
* Last 8-11: User numbers
* China Mobile: 134 159 158 188
* China Unicom: 130 133 189 156
* Pattern: starts with 1, second digit 3 5 8, total 11 digits
*/
QString phoneNumber = "18865475968";
std::regex pattern("^1(3|5|8)\\d{9}$");
std::string phoneString = phoneNumber.toStdString();
qDebug() << "Phone Number:" << phoneNumber;
// Perform matching
bool matchResult = std::regex_match(phoneString, pattern);
if(!matchResult)
{
qDebug() << "PhoneNumber" << "-->Invalid phone number.";
}
else
{
qDebug() << phoneNumber << "-->Valid phone number.";
}
}
MainWindow::~MainWindow()
{
}