commit f2fa0746a2862f5f977e8c7c10a41a6ccb5bf87b Author: hehaoyang <1109196436@qq.com> Date: Thu Jan 11 16:14:21 2024 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..133446b --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +debug/* +release/* +.qmake.stash +HxUtils.pro.* +Makefile* +*.Debug +*.Release \ No newline at end of file diff --git a/HxDisk.cpp b/HxDisk.cpp new file mode 100644 index 0000000..46ff3b4 --- /dev/null +++ b/HxDisk.cpp @@ -0,0 +1,113 @@ +#include "HxDisk.h" + +void HxDisk::mkpath(QString path) +{ + QDir dir; + + if (!dir.exists(path)) + dir.mkpath(path); +} + + +void HxDisk::mkpath(QStringList names) +{ + foreach (QString name, names) { + HxDisk::mkpath(name); + } +} + +bool HxDisk::exist(QString rootPath) +{ + foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes()) + { + if (rootPath == storage.rootPath()) + return true; + } + + return false; +} + + +bool HxDisk::empty(QString path) +{ + return QDir(path).removeRecursively(); +} + +QList HxDisk::mounted_volumes() +{ + QList storageinfos; + foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes()) + { + if (storage.isValid() && + storage.isReady() && + !storage.rootPath().isNull() && + !storage.isReadOnly()) + { +#ifndef Q_OS_WIN32 + if (storage.rootPath() == "/") + continue; + + if (storage.fileSystemType() != "ext4") + continue; +#endif + storageinfos.append(storage); + } + } + + return storageinfos; +} + +double HxDisk::total_size(QString rootPath) +{ + foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes()) + { + if (rootPath == storage.rootPath()) + return static_cast(storage.bytesTotal()) / 1024 / 1024 / 1024; + } + + return 0; +} + +double HxDisk::free_size(QString rootPath) +{ + foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes()) + { + if (rootPath == storage.rootPath()) + return static_cast(storage.bytesAvailable()) / 1024 / 1024 / 1024; + } + + return 0; +} + +int HxDisk::entry_info_list(QString path) +{ + QDir dir(path); + if (!dir.exists()) + return 0; + + /* 设置过滤器 */ + dir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); + + return dir.entryInfoList().count(); +} + +void HxDisk::remove(QString filepath) +{ + QFileInfo fileinfo(filepath); + + if (!fileinfo.exists()) + return; + + QFile::remove(fileinfo.filePath()); + + QDir dir(fileinfo.path()); + + while (entry_info_list(dir.path()) == 0) + { + dir.rmdir(dir.path()); + + /* 返回上一级目录 */ + if (!dir.cdUp()) + return; + } +} diff --git a/HxDisk.h b/HxDisk.h new file mode 100644 index 0000000..33ca507 --- /dev/null +++ b/HxDisk.h @@ -0,0 +1,65 @@ +#ifndef HXDISK_H +#define HXDISK_H + +#include "HxTrace.h" + +#include +#include + +class HxDisk +{ +public: + /** + * @brief 创建文件夹 + * @param path 路径 + */ + static void mkpath(QString path); + + + static void mkpath(QStringList names); + + /** + * @brief 判断盘符是否存在 + * @param rootPath 路径 + * @return + */ + static bool exist(QString rootPath); + + + static bool empty(QString path); + + /** + * @brief 遍历盘符信息 + * @return 返回磁盘信息 + */ + static QList mounted_volumes(); + + /** + * @brief 获取磁盘总空间大小 + * @param rootPath 路径 + * @return 总空间, 单位: G + */ + static double total_size(QString rootPath); + + /** + * @brief 获取磁盘剩余空间大小 + * @param rootPath 路径 + * @return 剩余空间, 单位: G + */ + static double free_size(QString rootPath); + + /** + * @brief 检索目录信息总数 + * @param path 目录路径 + * @return 文件总数 + */ + static int entry_info_list(QString path); + + /** + * @brief 删除文件并判断目录是否为空, 为空时删除目录 + * @param filepath 文件路径 + */ + static void remove(QString filepath); +}; + +#endif diff --git a/HxLog.cpp b/HxLog.cpp new file mode 100644 index 0000000..f8b7cf8 --- /dev/null +++ b/HxLog.cpp @@ -0,0 +1,26 @@ +#include "HxLog.h" + +#include +#include + +QMutex HxLog::mutex; + +void HxLog::append(QString title, QString message) +{ + mutex.lock(); + + auto current_time = QDateTime::currentDateTime(); + + QFile file(QString("log/%1.log").arg(current_time.toString("yyyyMMdd"))); + + if (file.open(QIODevice::WriteOnly | QIODevice::Append)) + { + auto data = QString("[%1] | [%2] | %3\r\n").arg(current_time.toString("yyyy-MM-dd HH:mm:ss"), title, message); + + file.write(data.toLocal8Bit()); + + file.close(); + } + + mutex.unlock(); +} diff --git a/HxLog.h b/HxLog.h new file mode 100644 index 0000000..c6d7f3f --- /dev/null +++ b/HxLog.h @@ -0,0 +1,15 @@ +#ifndef HXLOG_H +#define HXLOG_H + +#include + +class HxLog +{ +public: + static void append(QString title, QString message); + +private: + static QMutex mutex; +}; + +#endif // HXLOG_H diff --git a/HxProcess.cpp b/HxProcess.cpp new file mode 100644 index 0000000..d3dcd10 --- /dev/null +++ b/HxProcess.cpp @@ -0,0 +1,40 @@ +#include "HxProcess.h" + +//QString HxProcess::start(QString command) +//{ +// QString output; + +// auto process = new QProcess(); +// process->start("/bin/bash", QStringList() << "-c" << command); +// process->waitForFinished(); + +// output = QString(process->readAll()); + +// process->close(); + +// return output; +//} + + +QString HxProcess::start(QString command) +{ + QString output; + + auto array = command.split(" "); + + QString program = array.at(0); + QStringList arguments; + for (int i = 1; i < array.count(); i++) + arguments << array.at(i); + + QProcess process; + process.setProcessChannelMode(QProcess::MergedChannels); + process.start(program, arguments); + process.waitForFinished(); + + output = QString(process.readAll()); + + process.close(); + + return output; +} diff --git a/HxProcess.h b/HxProcess.h new file mode 100644 index 0000000..3944be3 --- /dev/null +++ b/HxProcess.h @@ -0,0 +1,19 @@ +#ifndef HXPROCESS_H +#define HXPROCESS_H + +#include +#include + +class HxProcess +{ +public: + /** + * @brief 同步启动进程 + * @param command 参数 + * @return + */ + static QString start(QString command); + +}; + +#endif // HXPROCESS_H diff --git a/HxSocket.cpp b/HxSocket.cpp new file mode 100644 index 0000000..5327ed6 --- /dev/null +++ b/HxSocket.cpp @@ -0,0 +1,93 @@ +#include "HxSocket.h" +#include "HxThread.h" + +#include + +HxSocket::HxSocket(quint16 port) +{ + connect(&server, &QTcpServer::newConnection, this, &HxSocket::new_connection); + server.listen(QHostAddress::Any, port); +} + +HxSocket::HxSocket(QString address, int port) +{ + is_reconnect = true; + + socket = new QTcpSocket(); + + connect(socket, &QTcpSocket::readyRead, this, &HxSocket::ready_read); + + connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()), Qt::QueuedConnection); + + connect(this, &HxSocket::reconnection_event, this, &HxSocket::reconnection); + + /* 域名解析 */ + QHostInfo info = QHostInfo::fromName(address); + + this->port = port; + this->address = info.addresses().at(0).toString(); + + reconnection(); +} + +void HxSocket::new_connection() +{ + if (socket != nullptr) + socket->abort(); + + socket = server.nextPendingConnection(); + + connect(socket, &QTcpSocket::readyRead, this, &HxSocket::ready_read); + + connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()), Qt::QueuedConnection); +} + +void HxSocket::write(QByteArray data) +{ + if (socket == nullptr || socket->state() != QTcpSocket::ConnectedState) + return; + + data.append('\n'); + + socket->write(data); + socket->flush(); +} + +void HxSocket::ready_read() +{ + QByteArray msg = socket->readAll(); + + emit data_receive_event(msg.data()); +} + +void HxSocket::disconnected() +{ + if (is_reconnect) + emit reconnection_event(); +} + +void HxSocket::reconnection() +{ + /* 取消已有的连接 */ + if (socket != nullptr) + socket->disconnectFromHost(); + + /* 连接服务器 */ + socket->connectToHost(address, port); + + /* 等待连接 */ + if (!socket->waitForConnected(500)) + { + /* 使用 QThread::msleep 延时,会使 Socket 出现接收不到事件信息 (槽无法响应) */ + // auto time = QTime::currentTime().addMSecs(10000); + // while (QTime::currentTime() < time) + // { + // QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + // QThread::msleep(100); + // } + + HxThread::sleep(10000); + + emit reconnection_event(); + } +} diff --git a/HxSocket.h b/HxSocket.h new file mode 100644 index 0000000..5fe5e74 --- /dev/null +++ b/HxSocket.h @@ -0,0 +1,41 @@ +#ifndef HXSOCKET_H +#define HXSOCKET_H + +#include +#include + +class HxSocket: public QObject +{ + Q_OBJECT +public: + HxSocket(quint16 port); + + HxSocket(QString address, int port); + +signals: + void data_receive_event(QByteArray data); + void reconnection_event(void); + +public slots: + void new_connection(); + + void write(QByteArray data); + + void ready_read(); + + void disconnected(); + + /** + * @brief 重连 + */ + void reconnection(); + +private: + int port; + QString address; + bool is_reconnect = false; + QTcpServer server; + QTcpSocket *socket = nullptr; +}; + +#endif // HXSOCKET_H diff --git a/HxSql.cpp b/HxSql.cpp new file mode 100644 index 0000000..01ae018 --- /dev/null +++ b/HxSql.cpp @@ -0,0 +1,38 @@ +#include "HxSql.h" +#include "HxTrace.h" + +#include +#include +#include +#include + +QSqlDatabase HxSql::open(QString filepath, QString connectionName) +{ + QSqlDatabase database; + if (QSqlDatabase::contains(connectionName)) + database = QSqlDatabase::database(connectionName); + else + database = QSqlDatabase::addDatabase("QSQLITE", connectionName); + + database.setDatabaseName(filepath); + + if (!database.open()) + { + QString bk_filepath = filepath + QString(".[%1].bk").arg(QDateTime::currentDateTime().toString("yyyyMMddHHmmss")); + + QFile::copy(filepath, bk_filepath); + + QFile::remove(filepath); + + HxTrace::debug_write_line("database", QString("file backup success. %1 => %2").arg(filepath).arg(bk_filepath)); + + database.open(); + } + + return database; +} + +void HxSql::close(QString connectionName) +{ + QSqlDatabase::removeDatabase(connectionName); +} diff --git a/HxSql.h b/HxSql.h new file mode 100644 index 0000000..3adfe2f --- /dev/null +++ b/HxSql.h @@ -0,0 +1,24 @@ +#ifndef HXSQL_H +#define HXSQL_H + +#include + +class HxSql +{ +public: + /** + * @brief 打开数据库 + * @param filepath 数据库文件路径 + * @param connectionName 连接名 + * @return QSqlDatabase 数据库对象 + */ + static QSqlDatabase open(QString filepath, QString connectionName); + + /** + * @brief 关闭数据库 + * @param connectionName 连接名 + */ + static void close(QString connectionName); +}; + +#endif // HXSQL_H diff --git a/HxSystem.cpp b/HxSystem.cpp new file mode 100644 index 0000000..9c60eaa --- /dev/null +++ b/HxSystem.cpp @@ -0,0 +1,218 @@ +#include "HxSystem.h" +#include "HxProcess.h" + +#include +#include + +static double m_memory_total = 0; +static double m_cpu_total = 0, m_cpu_use = 0; +static QMap> m_disk_rw_speed; + +QString HxSystem::get_cpu_model() +{ +#ifdef Q_OS_LINUX + return HxProcess::start("cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c").simplified().remove(0, 1); +#endif + +#ifdef Q_OS_WIN + QSettings *CPU = new QSettings("HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", QSettings::NativeFormat); + return CPU->value("ProcessorNameString").toString(); +#endif + + return ""; +} + +int HxSystem::get_logical_cpu_number(){return HxProcess::start("cat /proc/cpuinfo| grep \"processor\"| wc -l").toInt();} + +bool HxSystem::get_cpu_temp(double *temp) +{ + Q_UNUSED(temp); + +#ifdef Q_OS_LINUX + auto result = HxProcess::start("cat /sys/class/thermal/thermal_zone0/temp"); + + auto data = result.simplified(); + + if(data.isNull()) + return false; + + *temp = data.toDouble() / 1000; + + return true; +#endif + + return false; +} + +bool HxSystem::get_cpu_status(double *cpu_rate) +{ + Q_UNUSED(cpu_rate); + Q_UNUSED(m_cpu_use); + Q_UNUSED(m_cpu_total); + +#ifdef Q_OS_LINUX + auto result = HxProcess::start("cat /proc/stat"); + + auto list = result.split("\n")[0].simplified().split(" "); + + if(list.size() > 3) + { + double use = list[1].toDouble() + list[2].toDouble() + list[3].toDouble(); + + double total = 0; + + for(int i = 1; i < list.size(); i++) + total += list[i].toDouble(); + + if(total - m_cpu_total > 0) + { + *cpu_rate = (use - m_cpu_use) / (total - m_cpu_total) * 100.0; + m_cpu_total = total; + m_cpu_use = use; + + return true; + } + } +#endif + + return false; +} + +bool HxSystem::get_memory_status(double *memory_use, double *memory_total, double *swap_use, double *swap_total) +{ + auto result = HxProcess::start("free -m"); + + auto list = result.split("\n"); + + if(list.size() >= 3) + { + auto memory_list = list[1].simplified().split(" "); + auto swap_list = list[2].simplified().split(" "); + + if(memory_list.size() >=7) + { + *memory_use = memory_list[2].toDouble(); + *memory_total = memory_list[1].toDouble(); + + m_memory_total = *memory_total; + } + + if(swap_list.size() >= 4) + { + *swap_use = swap_list[2].toDouble(); + *swap_total = swap_list[1].toDouble(); + } + + return true; + } + return false; +} + +bool HxSystem::get_program_status(double *cpu_usage, double *virtual_memory, double *resident_memory) +{ + auto result = HxProcess::start(QString("ps u %1").arg(getpid())); + + auto list = result.split("\n"); + + if(list.size() > 1) + { + auto info = list[1].simplified().split(" "); + + *cpu_usage = info[2].toDouble(); + + *virtual_memory = info[4].toDouble() / 1024 / 1024; + + *resident_memory = info[5].toDouble() / 1024; + + return true; + } + + return false; +} + +bool HxSystem::get_harddisk_status(QString disk, QString *file_system, QString *size, QString *use, double *read_speed, double *write_speed) +{ + auto result = HxProcess::start(QString("df -h %1").arg(disk)); + + auto list = result.split("\n"); + + if(list.size() > 1) + { + auto array = list[1].simplified().split(" "); + *file_system = array[0]; + *size = array[1]; + *use = array[4]; + + result = HxProcess::start(QString("iostat -k -d | grep %1").arg((*file_system).split("/").last())); + array = result.simplified().split(" "); + if(array.size() == 6) + { + if(m_disk_rw_speed.contains(*file_system)) + { + auto rw_speed = m_disk_rw_speed.value(*file_system); + + *read_speed = (array[4].toDouble() - rw_speed[0]); + *write_speed = (array[5].toDouble() - rw_speed[1]); + + rw_speed[0] = array[4].toDouble(); + rw_speed[1] = array[5].toDouble(); + + m_disk_rw_speed[*file_system] = rw_speed; + } + else + { + QList values; + values.append(array[4].toDouble()); + values.append(array[5].toDouble()); + m_disk_rw_speed.insert(*file_system, values); + } + } + + return true; + } + + return false; +} + +bool HxSystem::get_harddisk_temperature(QString file_system, QString *temperature) +{ + auto result = HxProcess::start(QString("echo tvis | sudo -S hddtemp '%1'").arg(file_system)); + + *temperature = result.simplified().split(":").last(); + + if((*temperature).isEmpty()) + return false; + + return true; +} + + +bool HxSystem::get_harddisk_smart(QString file_system, QString *smart) +{ + auto result = HxProcess::start(QString("echo tvis | sudo -S smartctl -i %1 | grep 'SMART support is'").arg(file_system)); + if(result.indexOf("Unavailable") != -1) + { + *smart = QObject::tr("不支持"); + } + else if(result.indexOf("Disabled") != -1) + { + *smart = QObject::tr("未启用"); + } + else if(result.indexOf("Available") != -1) + { + result = HxProcess::start(QString("echo tvis | sudo smartctl -H %1 | grep 'SMART overall-health self-assessment test result'").arg(file_system)); + if(result.indexOf("PASSED") != -1) + { + *smart = QObject::tr("良好"); + } + else + { + *smart = QObject::tr("故障"); + } + } + else + return false; + + return true; +} + diff --git a/HxSystem.h b/HxSystem.h new file mode 100644 index 0000000..338df95 --- /dev/null +++ b/HxSystem.h @@ -0,0 +1,84 @@ +#ifndef HXSYSTEM_H +#define HXSYSTEM_H + +#include + +class HxSystem +{ +public: + /** + * @brief 获取系统cpu型号 + * @return 系统cpu型号 + */ + static QString get_cpu_model(); + + /** + * @brief 获取系统逻辑CPU的个数 + * @return 系统逻辑CPU的个数 + */ + static int get_logical_cpu_number(); + + /** + * @brief 获取系统cpu温度 + * @param temp cpu温度 + * @return true: 成功; false 失败; + */ + static bool get_cpu_temp(double *temp); + + /** + * @brief 获取系统cpu状态 + * @param cpu_rate cpu使用率 + * @return true: 成功; false 失败; + */ + static bool get_cpu_status(double *cpu_rate); + + /** + * @brief 获取系统内存状态 + * @param memory_use 已用内存 + * @param memory_total 内存总大小 + * @param swap_use 已用交换空间 + * @param swap_total 交换空间总大小 + * @return true: 成功; false 失败; + */ + static bool get_memory_status(double *memory_use, double *memory_total, double *swap_use, double *swap_total); + + /** + * @brief 获取程序状态 + * @param cpu_usage CPU使用率 + * @param virtual_memory 虚拟内存使用量 + * @param resident_memory 物理内存使用量 + * @return true: 成功; false 失败; + */ + static bool get_program_status(double *cpu_usage, double *virtual_memory, double *resident_memory); + + /** + * @brief 获取硬盘状态 + * @param disk 路径 + * @param file_system 文件系统(磁盘路径) + * @param size 总大小 + * @param use 已用大小 + * @param read_speed 读速度 + * @param write_speed 写速度 + * @return true: 成功; false 失败; + */ + static bool get_harddisk_status(QString disk, QString *file_system, QString *size, QString *use, double *read_speed, double *write_speed); + + /** + * @brief 获取硬盘温度 + * @param file_system 文件系统(磁盘路径) + * @param temperature 温度 + * @return true: 成功; false 失败; + */ + static bool get_harddisk_temperature(QString file_system, QString *temperature); + + /** + * @brief 获取硬盘健康状态 + * @param file_system 文件系统(磁盘路径) + * @param smart 健康状态 + * @return true: 成功; false 失败; + */ + static bool get_harddisk_smart(QString file_system, QString *smart); + +}; + +#endif // HXSYSTEM_H diff --git a/HxTask.cpp b/HxTask.cpp new file mode 100644 index 0000000..9776178 --- /dev/null +++ b/HxTask.cpp @@ -0,0 +1,7 @@ +#include "HxTask.h" + +#include +#include + +QMutex HxTask::mutex; +QMap HxTask::dispatchers; diff --git a/HxTask.h b/HxTask.h new file mode 100644 index 0000000..c14b5e9 --- /dev/null +++ b/HxTask.h @@ -0,0 +1,191 @@ +#ifndef HXTASK_H +#define HXTASK_H + +#include "HxTrace.h" +//#include "HxThread.h" + +#include + +class HxTask +{ +public: + /** + * @brief 停止 + * @param uuid 任务唯一编码 + */ + static void stop(QUuid uuid) + { + if (dispatchers.contains(uuid)) + { + dispatchers[uuid] = false; + } + } + + /** + * @brief 异步执行 + * @param object 操作对象类 + * @param fn 操作对象类中的成员函数 + */ + template + static QFuture invoke(Functor functor) + { + return QtConcurrent::run(functor); + } + + /** + * @brief 异步执行 + * @param object 操作对象类 + * @param fn 操作对象类中的成员函数 + */ + template + static void run(Class *object, T (Class::*fn)()) + { + QtConcurrent::run( + [=](Class *_object, T (Class::*_fn)()) + { + (_object->*_fn)(); + }, + object, fn); + } + + /** + * @brief 异步执行线程 + * @param uuid 任务唯一编码 + * @param object 操作对象类 + * @param fn 操作对象类中的成员函数 + * @param millisecond 函数执行间隔频率,单位毫秒 + */ + template + static void run(QUuid uuid, Class *object, T (Class::*fn)(), int millisecond) + { + dispatchers.insert(uuid, true); + + QtConcurrent::run( + [=](QUuid _uuid, Class *_object, T (Class::*_fn)(), int _millisecond) + { + HxTrace::debug_write_line("HxTask", QString("Thread: %1, start").arg(_uuid.toString())); + + while (dispatchers[_uuid]) + { + (_object->*_fn)(); + + QThread::msleep(_millisecond); + } + + HxTrace::debug_write_line("HxTask", QString("Thread: %1, stop").arg(_uuid.toString())); + + dispatchers.remove(_uuid); + }, + uuid, object, fn, millisecond); + } + + /** + * @brief 任务并行 + * @param object 操作对象类 + * @param fn1 操作对象类中的成员函数1 + * @param millisecond1 函数1执行间隔频率,单位毫秒 + * @param fn2 操作对象类中的成员函数2 + * @param millisecond2 函数2执行间隔频率,单位毫秒 + * @return 任务唯一编码 + */ + template + static QUuid invoke(Class *object, T (Class::*fn1)(), int millisecond1, T (Class::*fn2)(), int millisecond2) + { + QUuid uuid = QUuid::createUuid(); + + HxTask::run(uuid, object, fn1, millisecond1); + HxTask::run(uuid, object, fn2, millisecond2); + + return uuid; + } + + /** + * @brief 任务并行 + * @param uuid 任务唯一编码 + * @param object 操作对象类 + * @param fn1 操作对象类中的成员函数1 + * @param millisecond1 函数1执行间隔频率,单位毫秒 + * @param fn2 操作对象类中的成员函数2 + * @param millisecond2 函数2执行间隔频率,单位毫秒 + * @return 任务唯一编码 + */ + template + static void invoke(QUuid uuid, Class *object, T (Class::*fn1)(), int millisecond1, T (Class::*fn2)(), int millisecond2) + { + HxTask::run(uuid, object, fn1, millisecond1); + HxTask::run(uuid, object, fn2, millisecond2); + } + + /** + * @brief 任务并行 + * @param object 操作对象类 + * @param fn1 操作对象类中的成员函数1 + * @param millisecond1 函数1执行间隔频率,单位毫秒 + * @param fn2 操作对象类中的成员函数2 + * @param millisecond2 函数2执行间隔频率,单位毫秒 + * @param fn3 操作对象类中的成员函数3 + * @param millisecond3 函数3执行间隔频率,单位毫秒 + * @return 任务唯一编码 + */ + template + static QUuid invoke(Class *object, T (Class::*fn1)(), int millisecond1, T (Class::*fn2)(), int millisecond2, T (Class::*fn3)(), int millisecond3) + { + QUuid uuid = QUuid::createUuid(); + + HxTask::run(uuid, object, fn1, millisecond1); + HxTask::run(uuid, object, fn2, millisecond2); + HxTask::run(uuid, object, fn3, millisecond3); + + return uuid; + } + + /** + * @brief 任务并行 + * @param uuid 任务唯一编码 + * @param object 操作对象类 + * @param fn1 操作对象类中的成员函数1 + * @param millisecond1 函数1执行间隔频率,单位毫秒 + * @param fn2 操作对象类中的成员函数2 + * @param millisecond2 函数2执行间隔频率,单位毫秒 + * @param fn3 操作对象类中的成员函数3 + * @param millisecond3 函数3执行间隔频率,单位毫秒 + * @return 任务唯一编码 + */ + template + static void invoke(QUuid uuid, Class *object, T (Class::*fn1)(), int millisecond1, T (Class::*fn2)(), int millisecond2, T (Class::*fn3)(), int millisecond3) + { + HxTask::run(uuid, object, fn1, millisecond1); + HxTask::run(uuid, object, fn2, millisecond2); + HxTask::run(uuid, object, fn3, millisecond3); + } + +private: + /** + * @brief mutex + */ + static QMutex mutex; + + /** + * @brief dispatchers + */ + static QMap dispatchers; +}; + +class HxParalle +{ +public: + /** + * @brief 任务并行 + * @param object 操作对象类 + * @param fn1 操作对象类中的成员函数1 + * @param fn2 操作对象类中的成员函数2 + */ + template + static void invoke(Class *object, T (Class::*fn1)(), T (Class::*fn2)()) + { + HxTask::run(object, fn1); + HxTask::run(object, fn2); + } +}; + +#endif // HXTASK_H diff --git a/HxThread.cpp b/HxThread.cpp new file mode 100644 index 0000000..6322405 --- /dev/null +++ b/HxThread.cpp @@ -0,0 +1,40 @@ +#include "HxThread.h" + +HxThread::HxThread(int millisecond) { m_wait_time = millisecond; } + +void HxThread::stop() +{ + m_thread_status = false; + + while (!m_stop_flags) + msleep(100); +} + +void HxThread::sleep(int millisecond) +{ + auto time = QTime::currentTime().addMSecs(millisecond); + while( QTime::currentTime() < time ) + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); +} + +void HxThread::action() { } + +void HxThread::continue_with(){} + +void HxThread::run() +{ + m_stop_flags = false; + m_thread_status = true; + + while (m_thread_status) + { + action(); + + msleep(m_wait_time); + } + + /* Execution at completion */ + continue_with(); + + m_stop_flags = true; +} diff --git a/HxThread.h b/HxThread.h new file mode 100644 index 0000000..5b742a1 --- /dev/null +++ b/HxThread.h @@ -0,0 +1,60 @@ +#ifndef HXTHREAD_H +#define HXTHREAD_H + +#include +#include +#include + +class HxThread : public QThread +{ + Q_OBJECT +public: + /** + * @brief 线程类初始化 + * @param millisecond + */ + HxThread(int millisecond); + + /** + * @brief 停止 + */ + void stop(); + + static void sleep(int millisecond); + +protected: + /** + * @brief 线程任务 + */ + virtual void action(); + + /** + * @brief 线程任务结束后的处理任务 + */ + virtual void continue_with(); + + /** + * @brief 线程 + */ + virtual void run(); + +protected: + /** + * @brief 线程状态. true: 运行; false: 结束; + */ + bool m_thread_status = false; + +private: + /** + * @brief 线程轮询间隔, 单位毫秒 + * @ + */ + int m_wait_time; + + /** + * @brief 线程停止标志 + */ + bool m_stop_flags = true; +}; + +#endif // HXTHREAD_H diff --git a/HxTrace.cpp b/HxTrace.cpp new file mode 100644 index 0000000..20b6eda --- /dev/null +++ b/HxTrace.cpp @@ -0,0 +1,35 @@ +#include "HxTrace.h" + +#include + +void HxTrace::debug_write_line(QString title, QString message) +{ +#ifdef QT_DEBUG + qDebug("[%s] [%s] => %s", + qPrintable(QDateTime::currentDateTime().toString("yyyy/MM/dd HH:mm:ss")), + qPrintable(title), + qPrintable(message)); +#endif +} + +void HxTrace::debug_write_line(QString title, const char *format, ...) +{ +#ifdef QT_DEBUG + char output[1024]; + + va_list arg_list; + + va_start(arg_list, format); + +// vsprintf(output, format, arg_list); + + vsnprintf(output, 1024, format, arg_list); + + va_end(arg_list); + + qDebug("[%s] [%s] => %s", + qPrintable(QDateTime::currentDateTime().toString("yyyy/MM/dd HH:mm:ss")), + qPrintable(title), + output); +#endif +} diff --git a/HxTrace.h b/HxTrace.h new file mode 100644 index 0000000..7e6a5a3 --- /dev/null +++ b/HxTrace.h @@ -0,0 +1,24 @@ +#ifndef HXTRACE_H +#define HXTRACE_H + +#include + +class HxTrace +{ +public: + /** + * @brief 调试信息输出 + * @param title 标题 + * @param message 信息 + */ + static void debug_write_line(QString title, QString message); + + /** + * @brief 调试信息输出 + * @param title 标题 + * @param format 信息 + */ + static void debug_write_line(QString title, const char *format, ...); +}; + +#endif // HXTRACE_H diff --git a/HxUtils.pro b/HxUtils.pro new file mode 100644 index 0000000..92690c7 --- /dev/null +++ b/HxUtils.pro @@ -0,0 +1,57 @@ +QT -= gui +QT += concurrent +QT += sql +QT += network + +TEMPLATE = lib +CONFIG += staticlib +CONFIG += c++11 + +CONFIG += debug_and_release + +unix { + CONFIG(debug, debug|release){ + TARGET = debug/HxUtils + } else { + TARGET = release/HxUtils + } +} + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + HxDisk.cpp \ + HxLog.cpp \ + HxProcess.cpp \ + HxSocket.cpp \ + HxSql.cpp \ + HxSystem.cpp \ + HxTask.cpp \ + HxThread.cpp \ + HxTrace.cpp + +HEADERS += \ + HxDisk.h \ + HxLog.h \ + HxProcess.h \ + HxSocket.h \ + HxSql.h \ + HxSystem.h \ + HxThread.h \ + HxTask.h \ + HxTrace.h + +# Default rules for deployment. +unix { + target.path = $$[QT_INSTALL_PLUGINS]/generic +} +!isEmpty(target.path): INSTALLS += target