diff --git a/tool/comtool/api/api.pri b/tool/comtool/api/api.pri index b3c61ec..510574e 100644 --- a/tool/comtool/api/api.pri +++ b/tool/comtool/api/api.pri @@ -1,11 +1,11 @@ HEADERS += \ $$PWD/appconfig.h \ $$PWD/appdata.h \ - $$PWD/quihelper.h \ - $$PWD/quihelperdata.h + $$PWD/qthelper.h \ + $$PWD/qthelperdata.h SOURCES += \ $$PWD/appconfig.cpp \ $$PWD/appdata.cpp \ - $$PWD/quihelper.cpp \ - $$PWD/quihelperdata.cpp + $$PWD/qthelper.cpp \ + $$PWD/qthelperdata.cpp diff --git a/tool/comtool/api/appconfig.cpp b/tool/comtool/api/appconfig.cpp index c398e5d..5cd4e8e 100644 --- a/tool/comtool/api/appconfig.cpp +++ b/tool/comtool/api/appconfig.cpp @@ -1,5 +1,5 @@ #include "appconfig.h" -#include "quihelper.h" +#include "qthelper.h" QString AppConfig::ConfigFile = "config.ini"; QString AppConfig::SendFileName = "send.txt"; @@ -60,7 +60,7 @@ void AppConfig::readConfig() set.endGroup(); //配置文件不存在或者不全则重新生成 - if (!QUIHelper::checkIniFile(AppConfig::ConfigFile)) { + if (!QtHelper::checkIniFile(AppConfig::ConfigFile)) { writeConfig(); return; } diff --git a/tool/comtool/api/appdata.cpp b/tool/comtool/api/appdata.cpp index a0c1789..0d75b48 100644 --- a/tool/comtool/api/appdata.cpp +++ b/tool/comtool/api/appdata.cpp @@ -1,5 +1,5 @@ #include "appdata.h" -#include "quihelper.h" +#include "qthelper.h" QStringList AppData::Intervals = QStringList(); QStringList AppData::Datas = QStringList(); @@ -11,7 +11,7 @@ void AppData::readSendData() { //读取发送数据列表 AppData::Datas.clear(); - QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(AppData::SendFileName); + QString fileName = QString("%1/%2").arg(QtHelper::appPath()).arg(AppData::SendFileName); QFile file(fileName); if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) { while (!file.atEnd()) { @@ -39,7 +39,7 @@ void AppData::readDeviceData() //读取转发数据列表 AppData::Keys.clear(); AppData::Values.clear(); - QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(AppData::DeviceFileName); + QString fileName = QString("%1/%2").arg(QtHelper::appPath()).arg(AppData::DeviceFileName); QFile file(fileName); if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) { while (!file.atEnd()) { @@ -72,7 +72,7 @@ void AppData::saveData(const QString &data) return; } - QString fileName = QString("%1/%2.txt").arg(QUIHelper::appPath()).arg(STRDATETIME); + QString fileName = QString("%1/%2.txt").arg(QtHelper::appPath()).arg(STRDATETIME); QFile file(fileName); if (file.open(QFile::WriteOnly | QFile::Text)) { file.write(data.toUtf8()); diff --git a/tool/comtool/api/qthelper.cpp b/tool/comtool/api/qthelper.cpp new file mode 100644 index 0000000..1911055 --- /dev/null +++ b/tool/comtool/api/qthelper.cpp @@ -0,0 +1,1234 @@ +#include "qthelper.h" +#include "qnetworkinterface.h" +#include "qnetworkproxy.h" + +#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz")) + +QList QtHelper::getScreenRects(bool available) +{ + QList rects; +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + int screenCount = qApp->screens().count(); + QList screens = qApp->screens(); + for (int i = 0; i < screenCount; ++i) { + QScreen *screen = screens.at(i); + rects << (available ? screen->availableGeometry() : screen->geometry()); + } +#else + int screenCount = qApp->desktop()->screenCount(); + QDesktopWidget *desk = qApp->desktop(); + for (int i = 0; i < screenCount; ++i) { + rects << (available ? desk->availableGeometry(i) : desk->screenGeometry(i)); + } +#endif + return rects; +} + +int QtHelper::getScreenIndex() +{ + //需要对多个屏幕进行处理 + int screenIndex = 0; + QList rects = getScreenRects(false); + int count = rects.count(); + for (int i = 0; i < count; ++i) { + //找到当前鼠标所在屏幕 + QPoint pos = QCursor::pos(); + if (rects.at(i).contains(pos)) { + screenIndex = i; + break; + } + } + + return screenIndex; +} + +QRect QtHelper::getScreenRect(bool available) +{ + int screenIndex = getScreenIndex(); + QList rects = getScreenRects(available); + return rects.at(screenIndex); +} + +qreal QtHelper::getScreenRatio(bool devicePixel) +{ + qreal ratio = 1.0; + int screenIndex = getScreenIndex(); +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + QScreen *screen = qApp->screens().at(screenIndex); + if (devicePixel) { + //需要开启 AA_EnableHighDpiScaling 属性才能正常获取 + ratio = screen->devicePixelRatio() * 100; + } else { + ratio = screen->logicalDotsPerInch(); + } +#else + //Qt4不能动态识别缩放更改后的值 + ratio = qApp->desktop()->screen(screenIndex)->logicalDpiX(); +#endif + return ratio / 96; +} + +QRect QtHelper::checkCenterRect(QRect &rect, bool available) +{ + QRect deskRect = QtHelper::getScreenRect(available); + int formWidth = rect.width(); + int formHeight = rect.height(); + int deskWidth = deskRect.width(); + int deskHeight = deskRect.height(); + int formX = deskWidth / 2 - formWidth / 2 + deskRect.x(); + int formY = deskHeight / 2 - formHeight / 2; + rect = QRect(formX, formY, formWidth, formHeight); + return deskRect; +} + +int QtHelper::deskWidth() +{ + return getScreenRect().width(); +} + +int QtHelper::deskHeight() +{ + return getScreenRect().height(); +} + +QSize QtHelper::deskSize() +{ + return getScreenRect().size(); +} + +QWidget *QtHelper::centerBaseForm = 0; +void QtHelper::setFormInCenter(QWidget *form) +{ + int formWidth = form->width(); + int formHeight = form->height(); + + //如果=0表示采用系统桌面屏幕为参照 + QRect rect; + if (centerBaseForm == 0) { + rect = getScreenRect(); + } else { + rect = centerBaseForm->geometry(); + } + + int deskWidth = rect.width(); + int deskHeight = rect.height(); + QPoint movePoint(deskWidth / 2 - formWidth / 2 + rect.x(), deskHeight / 2 - formHeight / 2 + rect.y()); + form->move(movePoint); +} + +void QtHelper::showForm(QWidget *form) +{ + setFormInCenter(form); + form->show(); + + //判断宽高是否超过了屏幕分辨率,超过了则最大化显示 + //qDebug() << TIMEMS << form->size() << deskSize(); + if (form->width() + 20 > deskWidth() || form->height() + 50 > deskHeight()) { + QMetaObject::invokeMethod(form, "showMaximized", Qt::QueuedConnection); + } +} + +QString QtHelper::appName() +{ + //没有必要每次都获取,只有当变量为空时才去获取一次 + static QString name; + if (name.isEmpty()) { + name = qApp->applicationFilePath(); + //下面的方法主要为了过滤安卓的路径 lib程序名_armeabi-v7a/lib程序名_arm64-v8a + QStringList list = name.split("/"); + name = list.at(list.count() - 1).split(".").at(0); + name.replace("_armeabi-v7a", ""); + name.replace("_arm64-v8a", ""); + } + + return name; +} + +QString QtHelper::appPath() +{ + static QString path; + if (path.isEmpty()) { +#ifdef Q_OS_ANDROID + //默认安卓根目录 + path = "/storage/emulated/0"; + //带上程序名称作为目录 前面加个0方便排序 + path = path + "/0" + appName(); +#else + path = qApp->applicationDirPath(); +#endif + } + + return path; +} + +void QtHelper::getCurrentInfo(char *argv[], QString &path, QString &name) +{ + //必须用fromLocal8Bit保证中文路径正常 + QString argv0 = QString::fromLocal8Bit(argv[0]); + QFileInfo file(argv0); + path = file.path(); + name = file.baseName(); +} + +QString QtHelper::getIniValue(const QString &fileName, const QString &key) +{ + QString value; + QFile file(fileName); + if (file.open(QFile::ReadOnly | QFile::Text)) { + while (!file.atEnd()) { + QString line = file.readLine(); + if (line.startsWith(key)) { + line = line.replace("\n", ""); + line = line.trimmed(); + value = line.split("=").last(); + break; + } + } + } + return value; +} + +QString QtHelper::getIniValue(char *argv[], const QString &key, const QString &dir) +{ + QString path, name; + QtHelper::getCurrentInfo(argv, path, name); + QString fileName = QString("%1/%2%3.ini").arg(path).arg(dir).arg(name); + return getIniValue(fileName, key); +} + +QStringList QtHelper::getLocalIPs() +{ + static QStringList ips; + if (ips.count() == 0) { +#ifdef Q_OS_WASM + ips << "127.0.0.1"; +#else + QList netInterfaces = QNetworkInterface::allInterfaces(); + foreach (QNetworkInterface netInterface, netInterfaces) { + //移除虚拟机和抓包工具的虚拟网卡 + QString humanReadableName = netInterface.humanReadableName().toLower(); + if (humanReadableName.startsWith("vmware network adapter") || humanReadableName.startsWith("npcap loopback adapter")) { + continue; + } + + //过滤当前网络接口 + bool flag = (netInterface.flags() == (QNetworkInterface::IsUp | QNetworkInterface::IsRunning | QNetworkInterface::CanBroadcast | QNetworkInterface::CanMulticast)); + if (!flag) { + continue; + } + + QList addrs = netInterface.addressEntries(); + foreach (QNetworkAddressEntry addr, addrs) { + //只取出IPV4的地址 + if (addr.ip().protocol() != QAbstractSocket::IPv4Protocol) { + continue; + } + + QString ip4 = addr.ip().toString(); + if (ip4 != "127.0.0.1") { + ips << ip4; + } + } + } +#endif + } + + return ips; +} + +QList QtHelper::colors = QList(); +QList QtHelper::getColorList() +{ + //备用颜色集合 可以自行添加 + if (colors.count() == 0) { + colors << QColor(0, 176, 180) << QColor(0, 113, 193) << QColor(255, 192, 0); + colors << QColor(72, 103, 149) << QColor(185, 87, 86) << QColor(0, 177, 125); + colors << QColor(214, 77, 84) << QColor(71, 164, 233) << QColor(34, 163, 169); + colors << QColor(59, 123, 156) << QColor(162, 121, 197) << QColor(72, 202, 245); + colors << QColor(0, 150, 121) << QColor(111, 9, 176) << QColor(250, 170, 20); + } + + return colors; +} + +QStringList QtHelper::getColorNames() +{ + QList colors = getColorList(); + QStringList colorNames; + foreach (QColor color, colors) { + colorNames << color.name(); + } + return colorNames; +} + +QColor QtHelper::getRandColor() +{ + QList colors = getColorList(); + int index = getRandValue(0, colors.count(), true); + return colors.at(index); +} + +void QtHelper::initRand() +{ + //初始化随机数种子 + QTime t = QTime::currentTime(); + srand(t.msec() + t.second() * 1000); +} + +float QtHelper::getRandFloat(float min, float max) +{ + double diff = fabs(max - min); + double value = (double)(rand() % 100) / 100; + value = min + value * diff; + return value; +} + +double QtHelper::getRandValue(int min, int max, bool contansMin, bool contansMax) +{ + int value; +#if (QT_VERSION <= QT_VERSION_CHECK(5,10,0)) + //通用公式 a是起始值,n是整数的范围 + //int value = a + rand() % n; + if (contansMin) { + if (contansMax) { + value = min + 0 + (rand() % (max - min + 1)); + } else { + value = min + 0 + (rand() % (max - min + 0)); + } + } else { + if (contansMax) { + value = min + 1 + (rand() % (max - min + 0)); + } else { + value = min + 1 + (rand() % (max - min - 1)); + } + } +#else + if (contansMin) { + if (contansMax) { + value = QRandomGenerator::global()->bounded(min + 0, max + 1); + } else { + value = QRandomGenerator::global()->bounded(min + 0, max + 0); + } + } else { + if (contansMax) { + value = QRandomGenerator::global()->bounded(min + 1, max + 1); + } else { + value = QRandomGenerator::global()->bounded(min + 1, max + 0); + } + } +#endif + return value; +} + +QStringList QtHelper::getRandPoint(int count, float mainLng, float mainLat, float dotLng, float dotLat) +{ + //随机生成点坐标 + QStringList points; + for (int i = 0; i < count; ++i) { + //0.00881415 0.000442928 +#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0)) + float lngx = QRandomGenerator::global()->bounded(dotLng); + float latx = QRandomGenerator::global()->bounded(dotLat); +#else + float lngx = getRandFloat(dotLng / 10, dotLng); + float latx = getRandFloat(dotLat / 10, dotLat); +#endif + //需要先用精度转换成字符串 + QString lng2 = QString::number(mainLng + lngx, 'f', 8); + QString lat2 = QString::number(mainLat + latx, 'f', 8); + QString point = QString("%1,%2").arg(lng2).arg(lat2); + points << point; + } + + return points; +} + +int QtHelper::getRangeValue(int oldMin, int oldMax, int oldValue, int newMin, int newMax) +{ + return (((oldValue - oldMin) * (newMax - newMin)) / (oldMax - oldMin)) + newMin; +} + +QString QtHelper::getUuid() +{ + QString uuid = QUuid::createUuid().toString(); + uuid.replace("{", ""); + uuid.replace("}", ""); + return uuid; +} + +void QtHelper::checkPath(const QString &dirName) +{ + //相对路径需要补全完整路径 + QString path = dirName; + if (path.startsWith("./")) { + path.replace(".", ""); + path = QtHelper::appPath() + path; + } else if (!path.startsWith("/") && !path.contains(":/")) { + path = QtHelper::appPath() + "/" + path; + } + + //目录不存在则新建 + QDir dir(path); + if (!dir.exists()) { + dir.mkpath(path); + } +} + +void QtHelper::sleep(int msec, bool exec) +{ + if (msec <= 0) { + return; + } + + if (exec) { +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //阻塞方式延时(如果在主线程会卡住主界面) + QThread::msleep(msec); +#else + //非阻塞方式延时(不会卡住主界面/据说可能有问题) + QTime endTime = QTime::currentTime().addMSecs(msec); + while (QTime::currentTime() < endTime) { + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + } +#endif + } else { + //非阻塞方式延时(现在很多人推荐的方法) + QEventLoop loop; + QTimer::singleShot(msec, &loop, SLOT(quit())); + loop.exec(); + } +} + +void QtHelper::checkRun() +{ +#ifdef Q_OS_WIN + //延时1秒钟,等待程序释放完毕 + QtHelper::sleep(1000); + //创建共享内存,判断是否已经运行程序 + static QSharedMemory mem(QtHelper::appName()); + if (!mem.create(1)) { + QtHelper::showMessageBoxError("程序已运行, 软件将自动关闭!", 5, true); + exit(0); + } +#endif +} + +void QtHelper::setStyle() +{ + //打印下所有内置风格的名字 + qDebug() << TIMEMS << "QStyleFactory::keys" << QStyleFactory::keys(); + //设置内置风格 +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + qApp->setStyle("Fusion"); +#else + qApp->setStyle("Cleanlooks"); +#endif + + //设置指定颜色 + QPalette palette; + palette.setBrush(QPalette::Window, QColor("#F0F0F0")); + qApp->setPalette(palette); +} + +QFont QtHelper::addFont(const QString &fontFile, const QString &fontName) +{ + //判断图形字体是否存在,不存在则加入 + QFontDatabase fontDb; + if (!fontDb.families().contains(fontName)) { + int fontId = fontDb.addApplicationFont(fontFile); + QStringList listName = fontDb.applicationFontFamilies(fontId); + if (listName.count() == 0) { + qDebug() << QString("load %1 error").arg(fontName); + } + } + + //再次判断是否包含字体名称防止加载失败 + QFont font; + if (fontDb.families().contains(fontName)) { + font = QFont(fontName); +#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0)) + font.setHintingPreference(QFont::PreferNoHinting); +#endif + } + + return font; +} + +void QtHelper::setFont(int fontSize) +{ + //安卓套件在有些手机上默认字体不好看需要主动设置字体 + //网页套件需要主动加载中文字体才能正常显示中文 +#if (defined Q_OS_ANDROID) || (defined Q_OS_WASM) + QString fontFile = ":/font/DroidSansFallback.ttf"; + QString fontName = "Droid Sans Fallback"; + qApp->setFont(addFont(fontFile, fontName)); + return; +#endif + +#ifdef __arm__ + fontSize = 25; +#endif + + QFont font; + font.setFamily("MicroSoft Yahei"); + font.setPixelSize(fontSize); + qApp->setFont(font); +} + +void QtHelper::setCode(bool utf8) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //如果想要控制台打印信息中文正常就注释掉这个设置 + if (utf8) { + QTextCodec *codec = QTextCodec::codecForName("utf-8"); + QTextCodec::setCodecForLocale(codec); + } +#else +#if _MSC_VER + QTextCodec *codec = QTextCodec::codecForName("gbk"); +#else + QTextCodec *codec = QTextCodec::codecForName("utf-8"); +#endif + QTextCodec::setCodecForLocale(codec); + QTextCodec::setCodecForCStrings(codec); + QTextCodec::setCodecForTr(codec); +#endif +} + +void QtHelper::setTranslator(const QString &qmFile) +{ + //过滤下不存在的就不用设置了 + if (!QFile(qmFile).exists()) { + return; + } + + QTranslator *translator = new QTranslator(qApp); + if (translator->load(qmFile)) { + qApp->installTranslator(translator); + } +} + +#ifdef Q_OS_ANDROID +#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) +#include +#else +//Qt6中将相关类移到了core模块而且名字变了 +#include +#endif +#endif + +bool QtHelper::checkPermission(const QString &permission) +{ +#ifdef Q_OS_ANDROID +#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0) && QT_VERSION < QT_VERSION_CHECK(6,0,0)) + QtAndroid::PermissionResult result = QtAndroid::checkPermission(permission); + if (result == QtAndroid::PermissionResult::Denied) { + QtAndroid::requestPermissionsSync(QStringList() << permission); + result = QtAndroid::checkPermission(permission); + if (result == QtAndroid::PermissionResult::Denied) { + return false; + } + } +#else + QFuture result = QtAndroidPrivate::requestPermission(permission); + if (result.resultAt(0) == QtAndroidPrivate::PermissionResult::Denied) { + return false; + } +#endif +#endif + return true; +} + +void QtHelper::initAndroidPermission() +{ + //可以把所有要动态申请的权限都写在这里 + checkPermission("android.permission.CALL_PHONE"); + checkPermission("android.permission.SEND_SMS"); + checkPermission("android.permission.CAMERA"); + checkPermission("android.permission.READ_EXTERNAL_STORAGE"); + checkPermission("android.permission.WRITE_EXTERNAL_STORAGE"); + + checkPermission("android.permission.ACCESS_COARSE_LOCATION"); + checkPermission("android.permission.BLUETOOTH"); + checkPermission("android.permission.BLUETOOTH_SCAN"); + checkPermission("android.permission.BLUETOOTH_CONNECT"); + checkPermission("android.permission.BLUETOOTH_ADVERTISE"); +} + +void QtHelper::initAll(bool utf8, bool style, int fontSize) +{ + //初始化安卓权限 + QtHelper::initAndroidPermission(); + //初始化随机数种子 + QtHelper::initRand(); + //设置编码 + QtHelper::setCode(utf8); + //设置字体 + QtHelper::setFont(fontSize); + //设置样式风格 + if (style) { + QtHelper::setStyle(); + } + + //设置翻译文件支持多个 + QtHelper::setTranslator(":/qm/widgets.qm"); + QtHelper::setTranslator(":/qm/qt_zh_CN.qm"); + QtHelper::setTranslator(":/qm/designer_zh_CN.qm"); + + //设置不使用本地系统环境代理配置 + QNetworkProxyFactory::setUseSystemConfiguration(false); + //设置当前目录为程序可执行文件所在目录 + QDir::setCurrent(QtHelper::appPath()); + //Qt4中默认没有程序名称需要主动设置 +#if (QT_VERSION < QT_VERSION_CHECK(5,0,0)) + qApp->setApplicationName(QtHelper::appName()); +#endif +} + +void QtHelper::initMain(bool desktopSettingsAware, bool use96Dpi, bool logCritical) +{ +#ifdef Q_OS_WIN + //Qt6.5开始默认是ffmpeg后端但是不成熟需要换成系统的 + qputenv("QT_MEDIA_BACKEND", "windows"); +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //设置是否应用操作系统设置比如字体 + QApplication::setDesktopSettingsAware(desktopSettingsAware); +#endif + + bool highDpi = !use96Dpi; +#ifdef Q_OS_ANDROID + highDpi = true; +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,6,0)) + //开启高分屏缩放支持 + if (highDpi) { + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + } +#endif + +#ifdef Q_OS_WIN + if (use96Dpi) { + //Qt6中AA_Use96Dpi没效果必须下面方式设置强制指定缩放DPI + qputenv("QT_FONT_DPI", "96"); +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //不应用任何缩放 + QApplication::setAttribute(Qt::AA_Use96Dpi); +#endif + } +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) + //高分屏缩放策略 + QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor); +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //下面这行表示不打印Qt内部类的警告提示信息 + if (!logCritical) { + QLoggingCategory::setFilterRules("*.critical=false\n*.warning=false"); + } +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,4,0)) + //设置opengl共享上下文 + QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); +#endif +} + +void QtHelper::initOpenGL(quint8 type, bool checkCardEnable, bool checkVirtualSystem) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5,4,0)) + //设置opengl模式 AA_UseDesktopOpenGL(默认) AA_UseOpenGLES AA_UseSoftwareOpenGL + //在一些很旧的设备上或者对opengl支持很低的设备上需要使用AA_UseOpenGLES表示禁用硬件加速 + //如果开启的是AA_UseOpenGLES则无法使用硬件加速比如ffmpeg的dxva2 + if (type == 1) { + QApplication::setAttribute(Qt::AA_UseDesktopOpenGL); + } else if (type == 2) { + QApplication::setAttribute(Qt::AA_UseOpenGLES); + } else if (type == 3) { + QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); + } + + //检测显卡是否被禁用 + if (checkCardEnable && !isVideoCardEnable()) { + QApplication::setAttribute(Qt::AA_UseOpenGLES); + } + + //检测是否是虚拟机系统 + if (checkVirtualSystem && isVirtualSystem()) { + QApplication::setAttribute(Qt::AA_UseOpenGLES); + } +#endif +} + +QString QtHelper::doCmd(const QString &program, const QStringList &arguments, int timeout) +{ + QString result; +#ifndef Q_OS_WASM + QProcess p; + p.start(program, arguments); + p.waitForFinished(timeout); + result = QString::fromLocal8Bit(p.readAllStandardOutput()); + result.replace("\r", ""); + result.replace("\n", ""); + result = result.simplified(); + result = result.trimmed(); +#endif + return result; +} + +bool QtHelper::isVideoCardEnable() +{ + QString result; + bool videoCardEnable = true; + +#if defined(Q_OS_WIN) + QStringList args; + //wmic path win32_VideoController get name,Status + args << "path" << "win32_VideoController" << "get" << "name,Status"; + result = doCmd("wmic", args); +#endif + + //Name Status Intel(R) UHD Graphics 630 OK + //Name Status Intel(R) UHD Graphics 630 Error + if (result.contains("Error")) { + videoCardEnable = false; + } + + return videoCardEnable; +} + +bool QtHelper::isVirtualSystem() +{ + QString result; + bool virtualSystem = false; + +#if defined(Q_OS_WIN) + QStringList args; + //wmic computersystem get Model + args << "computersystem" << "get" << "Model"; + result = doCmd("wmic", args); +#elif defined(Q_OS_LINUX) + QStringList args; + //还有个命令需要root权限运行 dmidecode -s system-product-name 执行结果和win一样 + result = doCmd("lscpu", args); +#endif + + //Model MS-7C00 + //Model VMWare Virtual Platform + //Model VirtualBox Virtual Platform + //Model Alibaba Cloud ECS + if (result.contains("VMware") || result.contains("VirtualBox") || result.contains("Alibaba")) { + virtualSystem = true; + } + + return virtualSystem; +} + +QVector QtHelper::msgTypes = QVector() << 0 << 1 << 2 << 3 << 4; +QVector QtHelper::msgKeys = QVector() << QString::fromUtf8("发送") << QString::fromUtf8("接收") << QString::fromUtf8("解析") << QString::fromUtf8("错误") << QString::fromUtf8("提示"); +QVector QtHelper::msgColors = QVector() << QColor("#3BA372") << QColor("#EE6668") << QColor("#9861B4") << QColor("#FA8359") << QColor("#22A3A9"); +QString QtHelper::appendMsg(QTextEdit *textEdit, int type, const QString &data, int maxCount, int ¤tCount, bool clear, bool pause) +{ + if (clear) { + textEdit->clear(); + currentCount = 0; + return QString(); + } + + if (pause) { + return QString(); + } + + if (currentCount >= maxCount) { + textEdit->clear(); + currentCount = 0; + } + + //不同类型不同颜色显示 + QString strType; + int index = msgTypes.indexOf(type); + if (index >= 0) { + strType = msgKeys.at(index); + textEdit->setTextColor(msgColors.at(index)); + } + + //过滤回车换行符 + QString strData = data; + strData.replace("\r", ""); + strData.replace("\n", ""); + strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData); + textEdit->append(strData); + currentCount++; + return strData; +} + +void QtHelper::setFramelessForm(QWidget *widgetMain, bool tool, bool top, bool menu) +{ + widgetMain->setProperty("form", true); + widgetMain->setProperty("canMove", true); + + //根据设定逐个追加属性 +#ifdef __arm__ + widgetMain->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); +#else + widgetMain->setWindowFlags(Qt::FramelessWindowHint); +#endif + if (tool) { + widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::Tool); + } + if (top) { + widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowStaysOnTopHint); + } + if (menu) { + //如果是其他系统比如neokylin会产生系统边框 +#ifdef Q_OS_WIN + widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint); +#endif + } +} + +int QtHelper::showMessageBox(const QString &text, int type, int closeSec, bool exec) +{ + int result = 0; + if (type == 0) { + showMessageBoxInfo(text, closeSec, exec); + } else if (type == 1) { + showMessageBoxError(text, closeSec, exec); + } else if (type == 2) { + result = showMessageBoxQuestion(text); + } + + return result; +} + +void QtHelper::showMessageBoxInfo(const QString &text, int closeSec, bool exec) +{ + QMessageBox box(QMessageBox::Information, "提示", text); + box.setStandardButtons(QMessageBox::Yes); + box.setButtonText(QMessageBox::Yes, QString("确 定")); + box.exec(); + //QMessageBox::information(0, "提示", info, QMessageBox::Yes); +} + +void QtHelper::showMessageBoxError(const QString &text, int closeSec, bool exec) +{ + QMessageBox box(QMessageBox::Critical, "错误", text); + box.setStandardButtons(QMessageBox::Yes); + box.setButtonText(QMessageBox::Yes, QString("确 定")); + box.exec(); + //QMessageBox::critical(0, "错误", info, QMessageBox::Yes); +} + +int QtHelper::showMessageBoxQuestion(const QString &text) +{ + QMessageBox box(QMessageBox::Question, "询问", text); + box.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + box.setButtonText(QMessageBox::Yes, QString("确 定")); + box.setButtonText(QMessageBox::No, QString("取 消")); + return box.exec(); + //return QMessageBox::question(0, "询问", info, QMessageBox::Yes | QMessageBox::No); +} + +void QtHelper::initDialog(QFileDialog *dialog, const QString &title, const QString &acceptName, + const QString &dirName, bool native, int width, int height) +{ + //设置标题 + dialog->setWindowTitle(title); + //设置标签文本 + dialog->setLabelText(QFileDialog::Accept, acceptName); + dialog->setLabelText(QFileDialog::Reject, "取消(&C)"); + dialog->setLabelText(QFileDialog::LookIn, "查看"); + dialog->setLabelText(QFileDialog::FileName, "名称"); + dialog->setLabelText(QFileDialog::FileType, "类型"); + + //设置默认显示目录 + if (!dirName.isEmpty()) { + dialog->setDirectory(dirName); + } + + //设置对话框宽高 + if (width > 0 && height > 0) { +#ifdef Q_OS_ANDROID + bool horizontal = (QtHelper::deskWidth() > QtHelper::deskHeight()); + if (horizontal) { + width = QtHelper::deskWidth() / 2; + height = QtHelper::deskHeight() - 50; + } else { + width = QtHelper::deskWidth() - 10; + height = QtHelper::deskHeight() / 2; + } +#endif + dialog->setFixedSize(width, height); + } + + //设置是否采用本地对话框 + dialog->setOption(QFileDialog::DontUseNativeDialog, !native); + //设置只读可以取消右上角的新建按钮 + //dialog->setReadOnly(true); +} + +QString QtHelper::getDialogResult(QFileDialog *dialog) +{ + QString result; + if (dialog->exec() == QFileDialog::Accepted) { + result = dialog->selectedFiles().first(); + if (!result.contains(".")) { + //自动补全拓展名 保存文件(*.txt *.exe) + QString filter = dialog->selectedNameFilter(); + if (filter.contains("*.")) { + filter = filter.split("(").last(); + filter = filter.mid(0, filter.length() - 1); + //取出第一个作为拓展名 + if (!filter.contains("*.*")) { + filter = filter.split(" ").first(); + result = result + filter.mid(1, filter.length()); + } + } + } + } + return result; +} + +QString QtHelper::getOpenFileName(const QString &filter, const QString &dirName, const QString &fileName, + bool native, int width, int height) +{ + QFileDialog dialog; + initDialog(&dialog, "打开文件", "选择(&S)", dirName, native, width, height); + + //设置文件类型 + if (!filter.isEmpty()) { + dialog.setNameFilter(filter); + } + + //设置默认文件名称 + dialog.selectFile(fileName); + return getDialogResult(&dialog); +} + +QString QtHelper::getSaveFileName(const QString &filter, const QString &dirName, const QString &fileName, + bool native, int width, int height) +{ + QFileDialog dialog; + initDialog(&dialog, "保存文件", "保存(&S)", dirName, native, width, height); + + //设置文件类型 + if (!filter.isEmpty()) { + dialog.setNameFilter(filter); + } + + //设置默认文件名称 + dialog.selectFile(fileName); + //设置模态类型允许输入 + dialog.setWindowModality(Qt::WindowModal); + //设置置顶显示 + dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint); + return getDialogResult(&dialog); +} + +QString QtHelper::getExistingDirectory(const QString &dirName, bool native, int width, int height) +{ + QFileDialog dialog; + initDialog(&dialog, "选择目录", "选择(&S)", dirName, native, width, height); + dialog.setOption(QFileDialog::ReadOnly); + //设置只显示目录 +#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) + dialog.setFileMode(QFileDialog::DirectoryOnly); +#endif + dialog.setOption(QFileDialog::ShowDirsOnly); + return getDialogResult(&dialog); +} + +QString QtHelper::getXorEncryptDecrypt(const QString &value, char key) +{ + //矫正范围外的数据 + if (key < 0 || key >= 127) { + key = 127; + } + + //大概从5.9版本输出的加密密码字符串前面会加上 @String 字符 + QString result = value; + if (result.startsWith("@String")) { + result = result.mid(8, result.length() - 9); + } + + for (int i = 0; i < result.length(); ++i) { + result[i] = QChar(result.at(i).toLatin1() ^ key); + } + return result; +} + +quint8 QtHelper::getOrCode(const QByteArray &data) +{ + int len = data.length(); + quint8 result = 0; + for (int i = 0; i < len; ++i) { + result ^= data.at(i); + } + + return result; +} + +quint8 QtHelper::getCheckCode(const QByteArray &data) +{ + int len = data.length(); + quint8 temp = 0; + for (int i = 0; i < len; ++i) { + temp += data.at(i); + } + + return temp % 256; +} + +void QtHelper::initTableView(QTableView *tableView, int rowHeight, bool headVisible, bool edit, bool stretchLast) +{ + //设置弱属性用于应用qss特殊样式 + tableView->setProperty("model", true); + //取消自动换行 + tableView->setWordWrap(false); + //超出文本不显示省略号 + tableView->setTextElideMode(Qt::ElideNone); + //奇数偶数行颜色交替 + tableView->setAlternatingRowColors(false); + //垂直表头是否可见 + tableView->verticalHeader()->setVisible(headVisible); + //选中一行表头是否加粗 + tableView->horizontalHeader()->setHighlightSections(false); + //最后一行拉伸填充 + tableView->horizontalHeader()->setStretchLastSection(stretchLast); + //行标题最小宽度尺寸 + tableView->horizontalHeader()->setMinimumSectionSize(0); + //行标题最小高度,等同于和默认行高一致 + tableView->horizontalHeader()->setFixedHeight(rowHeight); + //默认行高 + tableView->verticalHeader()->setDefaultSectionSize(rowHeight); + //选中时一行整体选中 + tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + //只允许选择单个 + tableView->setSelectionMode(QAbstractItemView::SingleSelection); + + //表头不可单击 +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + tableView->horizontalHeader()->setSectionsClickable(false); +#else + tableView->horizontalHeader()->setClickable(false); +#endif + + //鼠标按下即进入编辑模式 + if (edit) { + tableView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::DoubleClicked); + } else { + tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + } +} + +void QtHelper::openFile(const QString &fileName, const QString &msg) +{ +#ifdef __arm__ + return; +#endif + //文件不存在则不用处理 + if (!QFile(fileName).exists()) { + return; + } + if (QtHelper::showMessageBoxQuestion(msg + "成功, 确定现在就打开吗?") == QMessageBox::Yes) { + QString url = QString("file:///%1").arg(fileName); + QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode)); + } +} + +bool QtHelper::checkIniFile(const QString &iniFile) +{ + //如果配置文件大小为0,则以初始值继续运行,并生成配置文件 + QFile file(iniFile); + if (file.size() == 0) { + return false; + } + + //如果配置文件不完整,则以初始值继续运行,并生成配置文件 + if (file.open(QFile::ReadOnly)) { + bool ok = true; + while (!file.atEnd()) { + QString line = file.readLine(); + line.replace("\r", ""); + line.replace("\n", ""); + QStringList list = line.split("="); + + if (list.count() == 2) { + QString key = list.at(0); + QString value = list.at(1); + if (value.isEmpty()) { + qDebug() << TIMEMS << "ini node no value" << key; + ok = false; + break; + } + } + } + + if (!ok) { + return false; + } + } else { + return false; + } + + return true; +} + +QString QtHelper::cutString(const QString &text, int len, int left, int right, bool file, const QString &mid) +{ + //如果指定了字符串分割则表示是文件名需要去掉拓展名 + QString result = text; + if (file && result.contains(".")) { + int index = result.lastIndexOf("."); + result = result.mid(0, index); + } + + //最终字符串格式为 前缀字符...后缀字符 + if (result.length() > len) { + result = QString("%1%2%3").arg(result.left(left)).arg(mid).arg(result.right(right)); + } + + return result; +} + +QRect QtHelper::getCenterRect(const QSize &imageSize, const QRect &widgetRect, int borderWidth, int scaleMode) +{ + QSize newSize = imageSize; + QSize widgetSize = widgetRect.size() - QSize(borderWidth * 1, borderWidth * 1); + + if (scaleMode == 0) { + if (newSize.width() > widgetSize.width() || newSize.height() > widgetSize.height()) { + newSize.scale(widgetSize, Qt::KeepAspectRatio); + } + } else if (scaleMode == 1) { + newSize.scale(widgetSize, Qt::KeepAspectRatio); + } else { + newSize = widgetSize; + } + + int x = widgetRect.center().x() - newSize.width() / 2; + int y = widgetRect.center().y() - newSize.height() / 2; + //不是2的倍数需要偏移1像素 + x += (x % 2 == 0 ? 1 : 0); + y += (y % 2 == 0 ? 1 : 0); + return QRect(x, y, newSize.width(), newSize.height()); +} + +void QtHelper::getScaledImage(QImage &image, const QSize &widgetSize, int scaleMode, bool fast) +{ + Qt::TransformationMode mode = fast ? Qt::FastTransformation : Qt::SmoothTransformation; + if (scaleMode == 0) { + if (image.width() > widgetSize.width() || image.height() > widgetSize.height()) { + image = image.scaled(widgetSize, Qt::KeepAspectRatio, mode); + } + } else if (scaleMode == 1) { + image = image.scaled(widgetSize, Qt::KeepAspectRatio, mode); + } else { + image = image.scaled(widgetSize, Qt::IgnoreAspectRatio, mode); + } +} + +QString QtHelper::getTimeString(qint64 time) +{ + time = time / 1000; + QString min = QString("%1").arg(time / 60, 2, 10, QChar('0')); + QString sec = QString("%2").arg(time % 60, 2, 10, QChar('0')); + return QString("%1:%2").arg(min).arg(sec); +} + +QString QtHelper::getTimeString(QElapsedTimer timer) +{ + return QString::number((float)timer.elapsed() / 1000, 'f', 3); +} + +QString QtHelper::getSizeString(quint64 size) +{ + float num = size; + QStringList list; + list << "KB" << "MB" << "GB" << "TB"; + + QString unit("bytes"); + QStringListIterator i(list); + while (num >= 1024.0 && i.hasNext()) { + unit = i.next(); + num /= 1024.0; + } + + return QString("%1 %2").arg(QString::number(num, 'f', 2)).arg(unit); +} + +//setSystemDateTime("2022", "07", "01", "12", "22", "55"); +void QtHelper::setSystemDateTime(const QString &year, const QString &month, const QString &day, const QString &hour, const QString &min, const QString &sec) +{ +#ifdef Q_OS_WIN + QProcess p(0); + //先设置日期 + p.start("cmd"); + p.waitForStarted(); + p.write(QString("date %1-%2-%3\n").arg(year).arg(month).arg(day).toLatin1()); + p.closeWriteChannel(); + p.waitForFinished(1000); + p.close(); + //再设置时间 + p.start("cmd"); + p.waitForStarted(); + p.write(QString("time %1:%2:%3.00\n").arg(hour).arg(min).arg(sec).toLatin1()); + p.closeWriteChannel(); + p.waitForFinished(1000); + p.close(); +#else + QString cmd = QString("date %1%2%3%4%5.%6").arg(month).arg(day).arg(hour).arg(min).arg(year).arg(sec); + //设置日期时间 + system(cmd.toLatin1()); + //硬件时钟同步 + system("hwclock -w"); +#endif +} + +void QtHelper::runWithSystem(bool autoRun) +{ + QtHelper::runWithSystem(qApp->applicationName(), qApp->applicationFilePath(), autoRun); +} + +void QtHelper::runWithSystem(const QString &fileName, const QString &filePath, bool autoRun) +{ +#ifdef Q_OS_WIN + //要转换成本地文件路径(不启动则文件路径为空即可) + QSettings reg("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat); + reg.setValue(fileName, autoRun ? QDir::toNativeSeparators(filePath) : ""); +#endif +} + +void QtHelper::runBin(const QString &path, const QString &name) +{ +#ifdef Q_OS_WIN + QString cmd1 = "tasklist"; + QString cmd2 = QString("%1/%2.exe").arg(path).arg(name); +#else + QString cmd1 = "ps -aux"; + QString cmd2 = QString("%1/%2").arg(path).arg(name); +#endif + +#ifndef Q_OS_WASM + QProcess p; + p.start(cmd1); + if (p.waitForFinished()) { + QString result = p.readAll(); + if (result.contains(name)) { + return; + } + } + + //加上引号可以兼容打开带空格的目录(Program Files) + if (cmd2.contains(" ")) { + cmd2 = "\"" + cmd2 + "\""; + } + + //QProcess::execute(cmd2); + QProcess::startDetached(cmd2); +#endif +} diff --git a/tool/netserver/api/quihelper.h b/tool/comtool/api/qthelper.h similarity index 55% rename from tool/netserver/api/quihelper.h rename to tool/comtool/api/qthelper.h index 759b1a7..6562b43 100644 --- a/tool/netserver/api/quihelper.h +++ b/tool/comtool/api/qthelper.h @@ -1,14 +1,19 @@ -#ifndef QUIHELPER2_H -#define QUIHELPER2_H +#ifndef QTHELPER_H +#define QTHELPER_H #include "head.h" -class QUIHelper +class QtHelper { public: - //获取当前鼠标所在屏幕索引+尺寸 + //获取所有屏幕区域/当前鼠标所在屏幕索引/区域尺寸/缩放系数 + static QList getScreenRects(bool available = true); static int getScreenIndex(); static QRect getScreenRect(bool available = true); + static qreal getScreenRatio(bool devicePixel = false); + + //矫正当前鼠标所在屏幕居中尺寸 + static QRect checkCenterRect(QRect &rect, bool available = true); //获取桌面宽度高度+居中显示 static int deskWidth(); @@ -21,10 +26,16 @@ public: static void setFormInCenter(QWidget *form); static void showForm(QWidget *form); - //程序文件名称+当前所在路径 + //程序文件名称和当前所在路径 static QString appName(); static QString appPath(); + //程序最前面获取应用程序路径和名称 + static void getCurrentInfo(char *argv[], QString &path, QString &name); + //程序最前面读取配置文件节点的值 + static QString getIniValue(const QString &fileName, const QString &key); + static QString getIniValue(char *argv[], const QString &key, const QString &dir = QString()); + //获取本地网卡IP集合 static QStringList getLocalIPs(); @@ -43,13 +54,17 @@ public: static double getRandValue(int min, int max, bool contansMin = false, bool contansMax = false); //获取范围值随机经纬度集合 static QStringList getRandPoint(int count, float mainLng, float mainLat, float dotLng, float dotLat); + //根据旧的范围值和值计算新的范围值对应的值 + static int getRangeValue(int oldMin, int oldMax, int oldValue, int newMin, int newMax); //获取uuid static QString getUuid(); - //可执行文件目录下新建目录 - static void newDir(const QString &dirName); - //延时 - static void sleep(int msec); + //校验目录 + static void checkPath(const QString &dirName); + //通用延时函数(支持Qt4 Qt5 Qt6) + static void sleep(int msec, bool exec = true); + //检查程序是否已经运行 + static void checkRun(); //设置Qt自带样式 static void setStyle(); @@ -61,10 +76,24 @@ public: //设置翻译文件 static void setTranslator(const QString &qmFile); + //动态设置权限 + static bool checkPermission(const QString &permission); + //申请安卓权限 + static void initAndroidPermission(); + //一次性设置所有包括编码样式字体等 static void initAll(bool utf8 = true, bool style = true, int fontSize = 13); //初始化main函数最前面执行的一段代码 - static void initMain(bool on = true); + static void initMain(bool desktopSettingsAware = false, bool use96Dpi = true, bool logCritical = true); + //初始化opengl类型(1=AA_UseDesktopOpenGL 2=AA_UseOpenGLES 3=AA_UseSoftwareOpenGL) + static void initOpenGL(quint8 type = 0, bool checkCardEnable = false, bool checkVirtualSystem = false); + + //执行命令行返回执行结果 + static QString doCmd(const QString &program, const QStringList &arguments, int timeout = 1000); + //获取显卡是否被禁用 + static bool isVideoCardEnable(); + //获取是否在虚拟机环境 + static bool isVirtualSystem(); //插入消息 static QVector msgTypes; @@ -78,13 +107,13 @@ public: static void setFramelessForm(QWidget *widgetMain, bool tool = false, bool top = false, bool menu = true); //弹出框 - static int showMessageBox(const QString &info, int type = 0, int closeSec = 0, bool exec = false); + static int showMessageBox(const QString &text, int type = 0, int closeSec = 0, bool exec = false); //弹出消息框 - static void showMessageBoxInfo(const QString &info, int closeSec = 0, bool exec = false); + static void showMessageBoxInfo(const QString &text, int closeSec = 0, bool exec = false); //弹出错误框 - static void showMessageBoxError(const QString &info, int closeSec = 0, bool exec = false); + static void showMessageBoxError(const QString &text, int closeSec = 0, bool exec = false); //弹出询问框 - static int showMessageBoxQuestion(const QString &info); + static int showMessageBoxQuestion(const QString &text); //为什么还要自定义对话框因为可控宽高和汉化对应文本等 //初始化对话框文本 @@ -109,9 +138,9 @@ public: //异或加密-只支持字符,如果是中文需要将其转换base64编码 static QString getXorEncryptDecrypt(const QString &value, char key); //异或校验 - static uchar getOrCode(const QByteArray &data); + static quint8 getOrCode(const QByteArray &data); //计算校验码 - static uchar getCheckCode(const QByteArray &data); + static quint8 getCheckCode(const QByteArray &data); //初始化表格 static void initTableView(QTableView *tableView, int rowHeight = 25, @@ -124,7 +153,28 @@ public: static bool checkIniFile(const QString &iniFile); //首尾截断字符串显示 - static QString cutString(const QString &text, int len, int left, int right, const QString &mid = "..."); + static QString cutString(const QString &text, int len, int left, int right, bool file, const QString &mid = "..."); + + //传入图片尺寸和窗体区域及边框大小返回居中区域(scaleMode: 0-自动调整 1-等比缩放 2-拉伸填充) + static QRect getCenterRect(const QSize &imageSize, const QRect &widgetRect, int borderWidth = 2, int scaleMode = 0); + //传入图片尺寸和窗体尺寸及缩放策略返回合适尺寸(scaleMode: 0-自动调整 1-等比缩放 2-拉伸填充) + static void getScaledImage(QImage &image, const QSize &widgetSize, int scaleMode = 0, bool fast = true); + + //毫秒数转时间 00:00 + static QString getTimeString(qint64 time); + //用时时间转秒数 + static QString getTimeString(QElapsedTimer timer); + //文件大小转 KB MB GB TB + static QString getSizeString(quint64 size); + + //设置系统时间 + static void setSystemDateTime(const QString &year, const QString &month, const QString &day, + const QString &hour, const QString &min, const QString &sec); + //设置开机自启动 + static void runWithSystem(bool autoRun = true); + static void runWithSystem(const QString &fileName, const QString &filePath, bool autoRun = true); + //启动运行程序(已经在运行则不启动) + static void runBin(const QString &path, const QString &name); }; -#endif // QUIHELPER2_H +#endif // QTHELPER_H diff --git a/tool/nettool/api/quihelperdata.cpp b/tool/comtool/api/qthelperdata.cpp similarity index 66% rename from tool/nettool/api/quihelperdata.cpp rename to tool/comtool/api/qthelperdata.cpp index 62b7f05..5f26ee5 100644 --- a/tool/nettool/api/quihelperdata.cpp +++ b/tool/comtool/api/qthelperdata.cpp @@ -1,29 +1,29 @@ -#include "quihelperdata.h" -#include "quihelper.h" +#include "qthelperdata.h" +#include "qthelper.h" -int QUIHelperData::strHexToDecimal(const QString &strHex) +int QtHelperData::strHexToDecimal(const QString &strHex) { bool ok; return strHex.toInt(&ok, 16); } -int QUIHelperData::strDecimalToDecimal(const QString &strDecimal) +int QtHelperData::strDecimalToDecimal(const QString &strDecimal) { bool ok; return strDecimal.toInt(&ok, 10); } -int QUIHelperData::strBinToDecimal(const QString &strBin) +int QtHelperData::strBinToDecimal(const QString &strBin) { bool ok; return strBin.toInt(&ok, 2); } -QString QUIHelperData::strHexToStrBin(const QString &strHex) +QString QtHelperData::strHexToStrBin(const QString &strHex) { - uchar decimal = strHexToDecimal(strHex); + quint8 decimal = strHexToDecimal(strHex); QString bin = QString::number(decimal, 2); - uchar len = bin.length(); + quint8 len = bin.length(); if (len < 8) { for (int i = 0; i < 8 - len; ++i) { @@ -34,10 +34,10 @@ QString QUIHelperData::strHexToStrBin(const QString &strHex) return bin; } -QString QUIHelperData::decimalToStrBin1(int decimal) +QString QtHelperData::decimalToStrBin1(int decimal) { QString bin = QString::number(decimal, 2); - uchar len = bin.length(); + quint8 len = bin.length(); if (len <= 8) { for (int i = 0; i < 8 - len; ++i) { bin = "0" + bin; @@ -47,10 +47,10 @@ QString QUIHelperData::decimalToStrBin1(int decimal) return bin; } -QString QUIHelperData::decimalToStrBin2(int decimal) +QString QtHelperData::decimalToStrBin2(int decimal) { QString bin = QString::number(decimal, 2); - uchar len = bin.length(); + quint8 len = bin.length(); if (len <= 16) { for (int i = 0; i < 16 - len; ++i) { bin = "0" + bin; @@ -60,7 +60,7 @@ QString QUIHelperData::decimalToStrBin2(int decimal) return bin; } -QString QUIHelperData::decimalToStrHex(int decimal) +QString QtHelperData::decimalToStrHex(int decimal) { QString temp = QString::number(decimal, 16); if (temp.length() == 1) { @@ -70,105 +70,80 @@ QString QUIHelperData::decimalToStrHex(int decimal) return temp; } -QByteArray QUIHelperData::intToByte(int data) +QByteArray QtHelperData::intToByte(int data, bool reverse) { + quint8 data1 = (quint8)(0x000000ff & data); + quint8 data2 = (quint8)((0x0000ff00 & data) >> 8); + quint8 data3 = (quint8)((0x00ff0000 & data) >> 16); + quint8 data4 = (quint8)((0xff000000 & data) >> 24); + QByteArray result; result.resize(4); - result[3] = (uchar)(0x000000ff & data); - result[2] = (uchar)((0x0000ff00 & data) >> 8); - result[1] = (uchar)((0x00ff0000 & data) >> 16); - result[0] = (uchar)((0xff000000 & data) >> 24); + if (reverse) { + result[0] = data1; + result[1] = data2; + result[2] = data3; + result[3] = data4; + } else { + result[0] = data4; + result[1] = data3; + result[2] = data2; + result[3] = data1; + } return result; } -QByteArray QUIHelperData::intToByteRec(int data) +int QtHelperData::byteToInt(const QByteArray &data, bool reverse) { - QByteArray result; - result.resize(4); - result[0] = (uchar)(0x000000ff & data); - result[1] = (uchar)((0x0000ff00 & data) >> 8); - result[2] = (uchar)((0x00ff0000 & data) >> 16); - result[3] = (uchar)((0xff000000 & data) >> 24); + int result = 0; + if (reverse) { + result = data.at(0) & 0x000000ff; + result |= ((data.at(1) << 8) & 0x0000ff00); + result |= ((data.at(2) << 16) & 0x00ff0000); + result |= ((data.at(3) << 24) & 0xff000000); + } else { + result = data.at(3) & 0x000000ff; + result |= ((data.at(2) << 8) & 0x0000ff00); + result |= ((data.at(1) << 16) & 0x00ff0000); + result |= ((data.at(0) << 24) & 0xff000000); + } return result; } -int QUIHelperData::byteToInt(const QByteArray &data) +QByteArray QtHelperData::ushortToByte(int data, bool reverse) { - int i = data.at(3) & 0x000000ff; - i |= ((data.at(2) << 8) & 0x0000ff00); - i |= ((data.at(1) << 16) & 0x00ff0000); - i |= ((data.at(0) << 24) & 0xff000000); - return i; -} + quint8 data1 = (quint8)(0x000000ff & data); + quint8 data2 = (quint8)((0x0000ff00 & data) >> 8); -int QUIHelperData::byteToIntRec(const QByteArray &data) -{ - int i = data.at(0) & 0x000000ff; - i |= ((data.at(1) << 8) & 0x0000ff00); - i |= ((data.at(2) << 16) & 0x00ff0000); - i |= ((data.at(3) << 24) & 0xff000000); - return i; -} - -quint32 QUIHelperData::byteToUInt(const QByteArray &data) -{ - quint32 i = data.at(3) & 0x000000ff; - i |= ((data.at(2) << 8) & 0x0000ff00); - i |= ((data.at(1) << 16) & 0x00ff0000); - i |= ((data.at(0) << 24) & 0xff000000); - return i; -} - -quint32 QUIHelperData::byteToUIntRec(const QByteArray &data) -{ - quint32 i = data.at(0) & 0x000000ff; - i |= ((data.at(1) << 8) & 0x0000ff00); - i |= ((data.at(2) << 16) & 0x00ff0000); - i |= ((data.at(3) << 24) & 0xff000000); - return i; -} - -QByteArray QUIHelperData::ushortToByte(ushort data) -{ QByteArray result; result.resize(2); - result[1] = (uchar)(0x000000ff & data); - result[0] = (uchar)((0x0000ff00 & data) >> 8); + if (reverse) { + result[0] = data1; + result[1] = data2; + } else { + result[0] = data2; + result[1] = data1; + } return result; } -QByteArray QUIHelperData::ushortToByteRec(ushort data) +int QtHelperData::byteToShort(const QByteArray &data, bool reverse) { - QByteArray result; - result.resize(2); - result[0] = (uchar)(0x000000ff & data); - result[1] = (uchar)((0x0000ff00 & data) >> 8); + int result = 0; + if (reverse) { + result = data.at(0) & 0x000000ff; + result |= ((data.at(1) << 8) & 0x0000ff00); + } else { + result = data.at(1) & 0x000000ff; + result |= ((data.at(0) << 8) & 0x0000ff00); + } + if (result >= 32768) { + result = result - 65536; + } return result; } -int QUIHelperData::byteToUShort(const QByteArray &data) -{ - int i = data.at(1) & 0x000000FF; - i |= ((data.at(0) << 8) & 0x0000FF00); - if (i >= 32768) { - i = i - 65536; - } - - return i; -} - -int QUIHelperData::byteToUShortRec(const QByteArray &data) -{ - int i = data.at(0) & 0x000000FF; - i |= ((data.at(1) << 8) & 0x0000FF00); - if (i >= 32768) { - i = i - 65536; - } - - return i; -} - -QString QUIHelperData::getValue(quint8 value) +QString QtHelperData::getValue(quint8 value) { QString result = QString::number(value); if (result.length() <= 1) { @@ -177,7 +152,36 @@ QString QUIHelperData::getValue(quint8 value) return result; } -QString QUIHelperData::getXorEncryptDecrypt(const QString &value, char key) +QString QtHelperData::trimmed(const QString &text, int type) +{ + QString temp = text; + QString pattern; + if (type == -1) { + pattern = "^ +\\s*"; + } else if (type == 0) { + pattern = "\\s"; + //temp.replace(" ", ""); + } else if (type == 1) { + pattern = "\\s* +$"; + } else if (type == 2) { + temp = temp.trimmed(); + } else if (type == 3) { + temp = temp.simplified(); + } + + //调用正则表达式移除空格 + if (!pattern.isEmpty()) { +#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0)) + temp.remove(QRegularExpression(pattern)); +#else + temp.remove(QRegExp(pattern)); +#endif + } + + return temp; +} + +QString QtHelperData::getXorEncryptDecrypt(const QString &value, char key) { //矫正范围外的数据 if (key < 0 || key >= 127) { @@ -190,17 +194,16 @@ QString QUIHelperData::getXorEncryptDecrypt(const QString &value, char key) result = result.mid(8, result.length() - 9); } - int count = result.count(); - for (int i = 0; i < count; ++i) { + for (int i = 0; i < result.length(); ++i) { result[i] = QChar(result.at(i).toLatin1() ^ key); } return result; } -uchar QUIHelperData::getOrCode(const QByteArray &data) +quint8 QtHelperData::getOrCode(const QByteArray &data) { int len = data.length(); - uchar result = 0; + quint8 result = 0; for (int i = 0; i < len; ++i) { result ^= data.at(i); } @@ -208,17 +211,27 @@ uchar QUIHelperData::getOrCode(const QByteArray &data) return result; } -uchar QUIHelperData::getCheckCode(const QByteArray &data) +quint8 QtHelperData::getCheckCode(const QByteArray &data) { int len = data.length(); - uchar temp = 0; - for (uchar i = 0; i < len; ++i) { + quint8 temp = 0; + for (int i = 0; i < len; ++i) { temp += data.at(i); } return temp % 256; } +void QtHelperData::getFullData(QByteArray &buffer) +{ + //计算校验码 + quint8 checkCode = getCheckCode(buffer); + //尾部插入校验码 + buffer.append(checkCode); + //头部插入固定帧头 + buffer.insert(0, 0x16); +} + //函数功能:计算CRC16 //参数1:*data 16位CRC校验数据, //参数2:len 数据流长度 @@ -226,7 +239,7 @@ uchar QUIHelperData::getCheckCode(const QByteArray &data) //参数4:table 16位CRC查找表 //正序CRC计算 -quint16 QUIHelperData::getCrc16(quint8 *data, int len, quint16 init, const quint16 *table) +quint16 QtHelperData::getCrc16(quint8 *data, int len, quint16 init, const quint16 *table) { quint16 crc_16 = init; quint8 temp; @@ -239,7 +252,7 @@ quint16 QUIHelperData::getCrc16(quint8 *data, int len, quint16 init, const quint } //逆序CRC计算 -quint16 QUIHelperData::getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table) +quint16 QtHelperData::getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table) { quint16 crc_16 = init; quint8 temp; @@ -252,7 +265,7 @@ quint16 QUIHelperData::getCrc16Rec(quint8 *data, int len, quint16 init, const qu } //Modbus CRC16校验 -quint16 QUIHelperData::getModbus16(quint8 *data, int len) +quint16 QtHelperData::getModbus16(quint8 *data, int len) { //MODBUS CRC-16表 8005 逆序 const quint16 table_16[256] = { @@ -294,14 +307,14 @@ quint16 QUIHelperData::getModbus16(quint8 *data, int len) } //CRC16校验 -QByteArray QUIHelperData::getCrcCode(const QByteArray &data) +QByteArray QtHelperData::getCrcCode(const QByteArray &data) { quint16 result = getModbus16((quint8 *)data.data(), data.length()); - return QUIHelperData::ushortToByteRec(result); + return QtHelperData::ushortToByte(result, true); } static QMap listChar; -void QUIHelperData::initAscii() +void QtHelperData::initAscii() { //0x20为空格,空格以下都是不可见字符 if (listChar.count() == 0) { @@ -342,13 +355,13 @@ void QUIHelperData::initAscii() } } -QString QUIHelperData::byteArrayToAsciiStr(const QByteArray &data) +QString QtHelperData::byteArrayToAsciiStr(const QByteArray &data) { //先初始化字符表 initAscii(); QString temp; - int len = data.size(); + int len = data.length(); for (int i = 0; i < len; ++i) { char byte = data.at(i); QString value = listChar.value(byte); @@ -366,7 +379,7 @@ QString QUIHelperData::byteArrayToAsciiStr(const QByteArray &data) return temp.trimmed(); } -QByteArray QUIHelperData::asciiStrToByteArray(const QString &data) +QByteArray QtHelperData::asciiStrToByteArray(const QString &data) { //先初始化字符表 initAscii(); @@ -388,14 +401,14 @@ QByteArray QUIHelperData::asciiStrToByteArray(const QString &data) } //可能是纯字符串不带控制字符 - if (buffer.size() == 0) { + if (buffer.length() == 0) { buffer = data.toUtf8(); } return buffer; } -char QUIHelperData::hexStrToChar(char data) +char QtHelperData::hexStrToChar(char data) { if ((data >= '0') && (data <= '9')) { return data - 0x30; @@ -408,7 +421,7 @@ char QUIHelperData::hexStrToChar(char data) } } -QByteArray QUIHelperData::hexStrToByteArray(const QString &data) +QByteArray QtHelperData::hexStrToByteArray(const QString &data) { QByteArray senddata; int hexdata, lowhexdata; @@ -448,7 +461,7 @@ QByteArray QUIHelperData::hexStrToByteArray(const QString &data) return senddata; } -QString QUIHelperData::byteArrayToHexStr(const QByteArray &data) +QString QtHelperData::byteArrayToHexStr(const QByteArray &data) { QString temp = ""; QString hex = data.toHex(); diff --git a/tool/netserver/api/quihelperdata.h b/tool/comtool/api/qthelperdata.h similarity index 65% rename from tool/netserver/api/quihelperdata.h rename to tool/comtool/api/qthelperdata.h index b5e3815..0f649c3 100644 --- a/tool/netserver/api/quihelperdata.h +++ b/tool/comtool/api/qthelperdata.h @@ -1,9 +1,9 @@ -#ifndef QUIHELPERDATA_H -#define QUIHELPERDATA_H +#ifndef QTHELPERDATA_H +#define QTHELPERDATA_H #include -class QUIHelperData +class QtHelperData { public: //16进制字符串转10进制 @@ -22,33 +22,28 @@ public: //10进制转16进制字符串,补零. static QString decimalToStrHex(int decimal); - //int转字节数组 - static QByteArray intToByte(int data); - static QByteArray intToByteRec(int data); + //int和字节数组互转 + static QByteArray intToByte(int data, bool reverse = false); + static int byteToInt(const QByteArray &data, bool reverse = false); - //字节数组转int - static int byteToInt(const QByteArray &data); - static int byteToIntRec(const QByteArray &data); - static quint32 byteToUInt(const QByteArray &data); - static quint32 byteToUIntRec(const QByteArray &data); - - //ushort转字节数组 - static QByteArray ushortToByte(ushort data); - static QByteArray ushortToByteRec(ushort data); - - //字节数组转ushort - static int byteToUShort(const QByteArray &data); - static int byteToUShortRec(const QByteArray &data); + //ushort和字节数组互转 + static QByteArray ushortToByte(int data, bool reverse = false); + static int byteToShort(const QByteArray &data, bool reverse = false); //字符串补全 static QString getValue(quint8 value); + //字符串去空格 -1=移除左侧空格 0=移除所有空格 1=移除右侧空格 2=移除首尾空格 3=首尾清除中间留一个空格 + static QString trimmed(const QString &text, int type); //异或加密-只支持字符,如果是中文需要将其转换base64编码 static QString getXorEncryptDecrypt(const QString &value, char key); //异或校验 - static uchar getOrCode(const QByteArray &data); - //计算校验码 - static uchar getCheckCode(const QByteArray &data); + static quint8 getOrCode(const QByteArray &data); + + //公司专用-计算校验码 + static quint8 getCheckCode(const QByteArray &data); + //公司专用-加上桢头和校验码完整数据 + static void getFullData(QByteArray &buffer); //CRC校验 static quint16 getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table); @@ -67,4 +62,4 @@ public: static QString byteArrayToHexStr(const QByteArray &data); }; -#endif // QUIHELPERDATA_H +#endif // QTHELPERDATA_H diff --git a/tool/comtool/api/quihelper.cpp b/tool/comtool/api/quihelper.cpp deleted file mode 100644 index 788147d..0000000 --- a/tool/comtool/api/quihelper.cpp +++ /dev/null @@ -1,818 +0,0 @@ -#include "quihelper.h" -#include "qnetworkinterface.h" -#include "qnetworkproxy.h" - -#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz")) -int QUIHelper::getScreenIndex() -{ - //需要对多个屏幕进行处理 - int screenIndex = 0; -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - int screenCount = qApp->screens().count(); -#else - int screenCount = qApp->desktop()->screenCount(); -#endif - - if (screenCount > 1) { - //找到当前鼠标所在屏幕 - QPoint pos = QCursor::pos(); - for (int i = 0; i < screenCount; ++i) { -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - if (qApp->screens().at(i)->geometry().contains(pos)) { -#else - if (qApp->desktop()->screenGeometry(i).contains(pos)) { -#endif - screenIndex = i; - break; - } - } - } - return screenIndex; -} - -QRect QUIHelper::getScreenRect(bool available) -{ - QRect rect; - int screenIndex = QUIHelper::getScreenIndex(); - if (available) { -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - rect = qApp->screens().at(screenIndex)->availableGeometry(); -#else - rect = qApp->desktop()->availableGeometry(screenIndex); -#endif - } else { -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - rect = qApp->screens().at(screenIndex)->geometry(); -#else - rect = qApp->desktop()->screenGeometry(screenIndex); -#endif - } - return rect; -} - -int QUIHelper::deskWidth() -{ - return getScreenRect().width(); -} - -int QUIHelper::deskHeight() -{ - return getScreenRect().height(); -} - -QSize QUIHelper::deskSize() -{ - return getScreenRect().size(); -} - -QWidget *QUIHelper::centerBaseForm = 0; -void QUIHelper::setFormInCenter(QWidget *form) -{ - int formWidth = form->width(); - int formHeight = form->height(); - - //如果=0表示采用系统桌面屏幕为参照 - QRect rect; - if (centerBaseForm == 0) { - rect = getScreenRect(); - } else { - rect = centerBaseForm->geometry(); - } - - int deskWidth = rect.width(); - int deskHeight = rect.height(); - QPoint movePoint(deskWidth / 2 - formWidth / 2 + rect.x(), deskHeight / 2 - formHeight / 2 + rect.y()); - form->move(movePoint); -} - -void QUIHelper::showForm(QWidget *form) -{ - setFormInCenter(form); - form->show(); - - //判断宽高是否超过了屏幕分辨率,超过了则最大化显示 - //qDebug() << TIMEMS << form->size() << deskSize(); - if (form->width() + 20 > deskWidth() || form->height() + 50 > deskHeight()) { - QMetaObject::invokeMethod(form, "showMaximized", Qt::QueuedConnection); - } -} - -QString QUIHelper::appName() -{ - //没有必要每次都获取,只有当变量为空时才去获取一次 - static QString name; - if (name.isEmpty()) { - name = qApp->applicationFilePath(); - //下面的方法主要为了过滤安卓的路径 lib程序名_armeabi-v7a - QStringList list = name.split("/"); - name = list.at(list.count() - 1).split(".").at(0); - name.replace("_armeabi-v7a", ""); - } - - return name; -} - -QString QUIHelper::appPath() -{ - static QString path; - if (path.isEmpty()) { -#ifdef Q_OS_ANDROID - //默认安卓根目录 - path = "/storage/emulated/0"; - //带上程序名称作为目录 前面加个0方便排序 - path = path + "/0" + appName(); -#else - path = qApp->applicationDirPath(); -#endif - } - - return path; -} - -QStringList QUIHelper::getLocalIPs() -{ - static QStringList ips; - if (ips.count() == 0) { -#ifdef Q_OS_WASM - ips << "127.0.0.1"; -#else - QList netInterfaces = QNetworkInterface::allInterfaces(); - foreach (const QNetworkInterface &netInterface, netInterfaces) { - //移除虚拟机和抓包工具的虚拟网卡 - QString humanReadableName = netInterface.humanReadableName().toLower(); - if (humanReadableName.startsWith("vmware network adapter") || humanReadableName.startsWith("npcap loopback adapter")) { - continue; - } - - //过滤当前网络接口 - bool flag = (netInterface.flags() == (QNetworkInterface::IsUp | QNetworkInterface::IsRunning | QNetworkInterface::CanBroadcast | QNetworkInterface::CanMulticast)); - if (!flag) { - continue; - } - - QList addrs = netInterface.addressEntries(); - foreach (QNetworkAddressEntry addr, addrs) { - //只取出IPV4的地址 - if (addr.ip().protocol() != QAbstractSocket::IPv4Protocol) { - continue; - } - - QString ip4 = addr.ip().toString(); - if (ip4 != "127.0.0.1") { - ips << ip4; - } - } - } -#endif - } - - return ips; -} - -QList QUIHelper::colors = QList(); -QList QUIHelper::getColorList() -{ - //备用颜色集合 可以自行添加 - if (colors.count() == 0) { - colors << QColor(0, 176, 180) << QColor(0, 113, 193) << QColor(255, 192, 0); - colors << QColor(72, 103, 149) << QColor(185, 87, 86) << QColor(0, 177, 125); - colors << QColor(214, 77, 84) << QColor(71, 164, 233) << QColor(34, 163, 169); - colors << QColor(59, 123, 156) << QColor(162, 121, 197) << QColor(72, 202, 245); - colors << QColor(0, 150, 121) << QColor(111, 9, 176) << QColor(250, 170, 20); - } - - return colors; -} - -QStringList QUIHelper::getColorNames() -{ - QList colors = getColorList(); - QStringList colorNames; - foreach (QColor color, colors) { - colorNames << color.name(); - } - return colorNames; -} - -QColor QUIHelper::getRandColor() -{ - QList colors = getColorList(); - int index = getRandValue(0, colors.count(), true); - return colors.at(index); -} - -void QUIHelper::initRand() -{ - //初始化随机数种子 - QTime t = QTime::currentTime(); - srand(t.msec() + t.second() * 1000); -} - -float QUIHelper::getRandFloat(float min, float max) -{ - double diff = fabs(max - min); - double value = (double)(rand() % 100) / 100; - value = min + value * diff; - return value; -} - -double QUIHelper::getRandValue(int min, int max, bool contansMin, bool contansMax) -{ - int value; -#if (QT_VERSION <= QT_VERSION_CHECK(5,10,0)) - //通用公式 a是起始值,n是整数的范围 - //int value = a + rand() % n; - if (contansMin) { - if (contansMax) { - value = min + 0 + (rand() % (max - min + 1)); - } else { - value = min + 0 + (rand() % (max - min + 0)); - } - } else { - if (contansMax) { - value = min + 1 + (rand() % (max - min + 0)); - } else { - value = min + 1 + (rand() % (max - min - 1)); - } - } -#else - if (contansMin) { - if (contansMax) { - value = QRandomGenerator::global()->bounded(min + 0, max + 1); - } else { - value = QRandomGenerator::global()->bounded(min + 0, max + 0); - } - } else { - if (contansMax) { - value = QRandomGenerator::global()->bounded(min + 1, max + 1); - } else { - value = QRandomGenerator::global()->bounded(min + 1, max + 0); - } - } -#endif - return value; -} - -QStringList QUIHelper::getRandPoint(int count, float mainLng, float mainLat, float dotLng, float dotLat) -{ - //随机生成点坐标 - QStringList points; - for (int i = 0; i < count; ++i) { - //0.00881415 0.000442928 -#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0)) - float lngx = QRandomGenerator::global()->bounded(dotLng); - float latx = QRandomGenerator::global()->bounded(dotLat); -#else - float lngx = getRandFloat(dotLng / 10, dotLng); - float latx = getRandFloat(dotLat / 10, dotLat); -#endif - //需要先用精度转换成字符串 - QString lng2 = QString::number(mainLng + lngx, 'f', 8); - QString lat2 = QString::number(mainLat + latx, 'f', 8); - QString point = QString("%1,%2").arg(lng2).arg(lat2); - points << point; - } - - return points; -} - -QString QUIHelper::getUuid() -{ - QString uuid = QUuid::createUuid().toString(); - uuid.replace("{", ""); - uuid.replace("}", ""); - return uuid; -} - -void QUIHelper::newDir(const QString &dirName) -{ - QString strDir = dirName; - - //如果路径中包含斜杠字符则说明是绝对路径 - //linux系统路径字符带有 / windows系统 路径字符带有 :/ - if (!strDir.startsWith("/") && !strDir.contains(":/")) { - strDir = QString("%1/%2").arg(QUIHelper::appPath()).arg(strDir); - } - - QDir dir(strDir); - if (!dir.exists()) { - dir.mkpath(strDir); - } -} - -void QUIHelper::sleep(int msec) -{ - if (msec <= 0) { - return; - } - -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - QThread::msleep(msec); -#else - QTime endTime = QTime::currentTime().addMSecs(msec); - while (QTime::currentTime() < endTime) { - QCoreApplication::processEvents(QEventLoop::AllEvents, 100); - } -#endif -} - -void QUIHelper::setStyle() -{ - //打印下所有内置风格的名字 - qDebug() << TIMEMS << "QStyleFactory::keys" << QStyleFactory::keys(); - //设置内置风格 -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - qApp->setStyle(QStyleFactory::create("Fusion")); -#else - qApp->setStyle(QStyleFactory::create("Cleanlooks")); -#endif - - //设置指定颜色 - QPalette palette; - palette.setBrush(QPalette::Window, QColor("#F0F0F0")); - qApp->setPalette(palette); -} - -QFont QUIHelper::addFont(const QString &fontFile, const QString &fontName) -{ - //判断图形字体是否存在,不存在则加入 - QFontDatabase fontDb; - if (!fontDb.families().contains(fontName)) { - int fontId = fontDb.addApplicationFont(fontFile); - QStringList listName = fontDb.applicationFontFamilies(fontId); - if (listName.count() == 0) { - qDebug() << QString("load %1 error").arg(fontName); - } - } - - //再次判断是否包含字体名称防止加载失败 - QFont font; - if (fontDb.families().contains(fontName)) { - font = QFont(fontName); -#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0)) - font.setHintingPreference(QFont::PreferNoHinting); -#endif - } - - return font; -} - -void QUIHelper::setFont(int fontSize) -{ -#ifdef rk3399 - return; -#endif - //安卓套件在有些手机上默认字体不好看需要主动设置字体 - //网页套件需要主动加载中文字体才能正常显示中文 -#if (defined Q_OS_ANDROID) || (defined Q_OS_WASM) - QString fontFile = ":/font/DroidSansFallback.ttf"; - QString fontName = "Droid Sans Fallback"; - qApp->setFont(addFont(fontFile, fontName)); - return; -#endif - -#ifdef __arm__ - fontSize = 25; -#endif -#ifdef Q_OS_ANDROID - fontSize = 15; -#endif - - QFont font; - font.setFamily("MicroSoft Yahei"); - font.setPixelSize(fontSize); - qApp->setFont(font); -} - -void QUIHelper::setCode(bool utf8) -{ -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - //如果想要控制台打印信息中文正常就注释掉这个设置 - if (utf8) { - QTextCodec *codec = QTextCodec::codecForName("utf-8"); - QTextCodec::setCodecForLocale(codec); - } -#else -#if _MSC_VER - QTextCodec *codec = QTextCodec::codecForName("gbk"); -#else - QTextCodec *codec = QTextCodec::codecForName("utf-8"); -#endif - QTextCodec::setCodecForLocale(codec); - QTextCodec::setCodecForCStrings(codec); - QTextCodec::setCodecForTr(codec); -#endif -} - -void QUIHelper::setTranslator(const QString &qmFile) -{ - //过滤下不存在的就不用设置了 - if (!QFile(qmFile).exists()) { - return; - } - - QTranslator *translator = new QTranslator(qApp); - if (translator->load(qmFile)) { - qApp->installTranslator(translator); - } -} - -void QUIHelper::initAll(bool utf8, bool style, int fontSize) -{ - //初始化随机数种子 - QUIHelper::initRand(); - //设置编码 - QUIHelper::setCode(utf8); - //设置样式风格 - if (style) { - QUIHelper::setStyle(); - } - //设置字体 - QUIHelper::setFont(fontSize); - //设置翻译文件支持多个 - QUIHelper::setTranslator(":/qm/widgets.qm"); - QUIHelper::setTranslator(":/qm/qt_zh_CN.qm"); - QUIHelper::setTranslator(":/qm/designer_zh_CN.qm"); - //设置不使用本地系统环境代理配置 - QNetworkProxyFactory::setUseSystemConfiguration(false); -} - -void QUIHelper::initMain(bool on) -{ - //设置是否应用操作系统设置比如字体 - QApplication::setDesktopSettingsAware(on); - -#ifdef Q_OS_ANDROID -#if (QT_VERSION >= QT_VERSION_CHECK(5,6,0)) - //开启高分屏缩放支持 - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif -#else -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - //不应用任何缩放 - QApplication::setAttribute(Qt::AA_Use96Dpi); -#endif -#endif - -#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) - //高分屏缩放策略 - QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor); -#endif - -#if (QT_VERSION >= QT_VERSION_CHECK(5,4,0)) - //设置opengl模式 AA_UseDesktopOpenGL(默认) AA_UseOpenGLES AA_UseSoftwareOpenGL - //在一些很旧的设备上或者对opengl支持很低的设备上需要使用AA_UseOpenGLES表示禁用硬件加速 - //如果开启的是AA_UseOpenGLES则无法使用硬件加速比如ffmpeg的dxva2 - //QApplication::setAttribute(Qt::AA_UseOpenGLES); - //设置opengl共享上下文 - QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); -#endif -} - -QVector QUIHelper::msgTypes = QVector() << 0 << 1 << 2 << 3 << 4; -QVector QUIHelper::msgKeys = QVector() << "发送" << "接收" << "解析" << "错误" << "提示"; -QVector QUIHelper::msgColors = QVector() << QColor("#3BA372") << QColor("#EE6668") << QColor("#9861B4") << QColor("#FA8359") << QColor("#22A3A9"); -QString QUIHelper::appendMsg(QTextEdit *textEdit, int type, const QString &data, int maxCount, int ¤tCount, bool clear, bool pause) -{ - if (clear) { - textEdit->clear(); - currentCount = 0; - return QString(); - } - - if (pause) { - return QString(); - } - - if (currentCount >= maxCount) { - textEdit->clear(); - currentCount = 0; - } - - //不同类型不同颜色显示 - QString strType; - int index = msgTypes.indexOf(type); - if (index >= 0) { - strType = msgKeys.at(index); - textEdit->setTextColor(msgColors.at(index)); - } - - //过滤回车换行符 - QString strData = data; - strData.replace("\r", ""); - strData.replace("\n", ""); - strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData); - textEdit->append(strData); - currentCount++; - return strData; -} - -void QUIHelper::setFramelessForm(QWidget *widgetMain, bool tool, bool top, bool menu) -{ - widgetMain->setProperty("form", true); - widgetMain->setProperty("canMove", true); - - //根据设定逐个追加属性 -#ifdef __arm__ - widgetMain->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); -#else - widgetMain->setWindowFlags(Qt::FramelessWindowHint); -#endif - if (tool) { - widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::Tool); - } - if (top) { - widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowStaysOnTopHint); - } - if (menu) { - //如果是其他系统比如neokylin会产生系统边框 -#ifdef Q_OS_WIN - widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint); -#endif - } -} - -int QUIHelper::showMessageBox(const QString &info, int type, int closeSec, bool exec) -{ - int result = 0; - if (type == 0) { - showMessageBoxInfo(info, closeSec, exec); - } else if (type == 1) { - showMessageBoxError(info, closeSec, exec); - } else if (type == 2) { - result = showMessageBoxQuestion(info); - } - - return result; -} - -void QUIHelper::showMessageBoxInfo(const QString &info, int closeSec, bool exec) -{ - QMessageBox box(QMessageBox::Information, "提示", info); - box.setStandardButtons(QMessageBox::Yes); - box.setButtonText(QMessageBox::Yes, QString("确 定")); - box.exec(); - //QMessageBox::information(0, "提示", info, QMessageBox::Yes); -} - -void QUIHelper::showMessageBoxError(const QString &info, int closeSec, bool exec) -{ - QMessageBox box(QMessageBox::Critical, "错误", info); - box.setStandardButtons(QMessageBox::Yes); - box.setButtonText(QMessageBox::Yes, QString("确 定")); - box.exec(); - //QMessageBox::critical(0, "错误", info, QMessageBox::Yes); -} - -int QUIHelper::showMessageBoxQuestion(const QString &info) -{ - QMessageBox box(QMessageBox::Question, "询问", info); - box.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - box.setButtonText(QMessageBox::Yes, QString("确 定")); - box.setButtonText(QMessageBox::No, QString("取 消")); - return box.exec(); - //return QMessageBox::question(0, "询问", info, QMessageBox::Yes | QMessageBox::No); -} - -void QUIHelper::initDialog(QFileDialog *dialog, const QString &title, const QString &acceptName, - const QString &dirName, bool native, int width, int height) -{ - //设置标题 - dialog->setWindowTitle(title); - //设置标签文本 - dialog->setLabelText(QFileDialog::Accept, acceptName); - dialog->setLabelText(QFileDialog::Reject, "取消(&C)"); - dialog->setLabelText(QFileDialog::LookIn, "查看"); - dialog->setLabelText(QFileDialog::FileName, "名称"); - dialog->setLabelText(QFileDialog::FileType, "类型"); - - //设置默认显示目录 - if (!dirName.isEmpty()) { - dialog->setDirectory(dirName); - } - - //设置对话框宽高 - if (width > 0 && height > 0) { -#ifdef Q_OS_ANDROID - bool horizontal = (QUIHelper::deskWidth() > QUIHelper::deskHeight()); - if (horizontal) { - width = QUIHelper::deskWidth() / 2; - height = QUIHelper::deskHeight() - 50; - } else { - width = QUIHelper::deskWidth() - 10; - height = QUIHelper::deskHeight() / 2; - } -#endif - dialog->setFixedSize(width, height); - } - - //设置是否采用本地对话框 - dialog->setOption(QFileDialog::DontUseNativeDialog, !native); - //设置只读可以取消右上角的新建按钮 - //dialog->setReadOnly(true); -} - -QString QUIHelper::getDialogResult(QFileDialog *dialog) -{ - QString result; - if (dialog->exec() == QFileDialog::Accepted) { - result = dialog->selectedFiles().first(); - } - return result; -} - -QString QUIHelper::getOpenFileName(const QString &filter, const QString &dirName, const QString &fileName, - bool native, int width, int height) -{ - QFileDialog dialog; - initDialog(&dialog, "打开文件", "选择(&S)", dirName, native, width, height); - - //设置文件类型 - if (!filter.isEmpty()) { - dialog.setNameFilter(filter); - } - - //设置默认文件名称 - dialog.selectFile(fileName); - return getDialogResult(&dialog); -} - -QString QUIHelper::getSaveFileName(const QString &filter, const QString &dirName, const QString &fileName, - bool native, int width, int height) -{ - QFileDialog dialog; - initDialog(&dialog, "保存文件", "保存(&S)", dirName, native, width, height); - - //设置文件类型 - if (!filter.isEmpty()) { - dialog.setNameFilter(filter); - } - - //设置默认文件名称 - dialog.selectFile(fileName); - //设置模态类型允许输入 - dialog.setWindowModality(Qt::WindowModal); - //设置置顶显示 - dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint); - return getDialogResult(&dialog); -} - -QString QUIHelper::getExistingDirectory(const QString &dirName, bool native, int width, int height) -{ - QFileDialog dialog; - initDialog(&dialog, "选择目录", "选择(&S)", dirName, native, width, height); - dialog.setOption(QFileDialog::ReadOnly); - //设置只显示目录 -#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) - dialog.setFileMode(QFileDialog::DirectoryOnly); -#endif - dialog.setOption(QFileDialog::ShowDirsOnly); - return getDialogResult(&dialog); -} - -QString QUIHelper::getXorEncryptDecrypt(const QString &value, char key) -{ - //矫正范围外的数据 - if (key < 0 || key >= 127) { - key = 127; - } - - //大概从5.9版本输出的加密密码字符串前面会加上 @String 字符 - QString result = value; - if (result.startsWith("@String")) { - result = result.mid(8, result.length() - 9); - } - - int count = result.count(); - for (int i = 0; i < count; ++i) { - result[i] = QChar(result.at(i).toLatin1() ^ key); - } - return result; -} - -uchar QUIHelper::getOrCode(const QByteArray &data) -{ - int len = data.length(); - uchar result = 0; - for (int i = 0; i < len; ++i) { - result ^= data.at(i); - } - - return result; -} - -uchar QUIHelper::getCheckCode(const QByteArray &data) -{ - int len = data.length(); - uchar temp = 0; - for (uchar i = 0; i < len; ++i) { - temp += data.at(i); - } - - return temp % 256; -} - -void QUIHelper::initTableView(QTableView *tableView, int rowHeight, bool headVisible, bool edit, bool stretchLast) -{ - //设置弱属性用于应用qss特殊样式 - tableView->setProperty("model", true); - //取消自动换行 - tableView->setWordWrap(false); - //超出文本不显示省略号 - tableView->setTextElideMode(Qt::ElideNone); - //奇数偶数行颜色交替 - tableView->setAlternatingRowColors(false); - //垂直表头是否可见 - tableView->verticalHeader()->setVisible(headVisible); - //选中一行表头是否加粗 - tableView->horizontalHeader()->setHighlightSections(false); - //最后一行拉伸填充 - tableView->horizontalHeader()->setStretchLastSection(stretchLast); - //行标题最小宽度尺寸 - tableView->horizontalHeader()->setMinimumSectionSize(0); - //行标题最小高度,等同于和默认行高一致 - tableView->horizontalHeader()->setFixedHeight(rowHeight); - //默认行高 - tableView->verticalHeader()->setDefaultSectionSize(rowHeight); - //选中时一行整体选中 - tableView->setSelectionBehavior(QAbstractItemView::SelectRows); - //只允许选择单个 - tableView->setSelectionMode(QAbstractItemView::SingleSelection); - - //表头不可单击 -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - tableView->horizontalHeader()->setSectionsClickable(false); -#else - tableView->horizontalHeader()->setClickable(false); -#endif - - //鼠标按下即进入编辑模式 - if (edit) { - tableView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::DoubleClicked); - } else { - tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); - } -} - -void QUIHelper::openFile(const QString &fileName, const QString &msg) -{ -#ifdef __arm__ - return; -#endif - //文件不存在则不用处理 - if (!QFile(fileName).exists()) { - return; - } - if (QUIHelper::showMessageBoxQuestion(msg + "成功, 确定现在就打开吗?") == QMessageBox::Yes) { - QString url = QString("file:///%1").arg(fileName); - QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode)); - } -} - -bool QUIHelper::checkIniFile(const QString &iniFile) -{ - //如果配置文件大小为0,则以初始值继续运行,并生成配置文件 - QFile file(iniFile); - if (file.size() == 0) { - return false; - } - - //如果配置文件不完整,则以初始值继续运行,并生成配置文件 - if (file.open(QFile::ReadOnly)) { - bool ok = true; - while (!file.atEnd()) { - QString line = file.readLine(); - line.replace("\r", ""); - line.replace("\n", ""); - QStringList list = line.split("="); - - if (list.count() == 2) { - QString key = list.at(0); - QString value = list.at(1); - if (value.isEmpty()) { - qDebug() << TIMEMS << "ini node no value" << key; - ok = false; - break; - } - } - } - - if (!ok) { - return false; - } - } else { - return false; - } - - return true; -} - -QString QUIHelper::cutString(const QString &text, int len, int left, int right, const QString &mid) -{ - //如果是文件名则取文件名的前字符+末尾字符+去掉拓展名 - QString result = text.split(".").first(); - if (result.length() > len) { - result = QString("%1%2%3").arg(result.left(left)).arg(mid).arg(result.right(right)); - } - return result; -} diff --git a/tool/comtool/form/frmcomtool.cpp b/tool/comtool/form/frmcomtool.cpp index a4ed141..86f88ee 100644 --- a/tool/comtool/form/frmcomtool.cpp +++ b/tool/comtool/form/frmcomtool.cpp @@ -1,14 +1,14 @@ #include "frmcomtool.h" #include "ui_frmcomtool.h" -#include "quihelper.h" -#include "quihelperdata.h" +#include "qthelper.h" +#include "qthelperdata.h" frmComTool::frmComTool(QWidget *parent) : QWidget(parent), ui(new Ui::frmComTool) { ui->setupUi(this); this->initForm(); this->initConfig(); - QUIHelper::setFormInCenter(this); + QtHelper::setFormInCenter(this); } frmComTool::~frmComTool() @@ -304,7 +304,7 @@ void frmComTool::readData() return; } - QUIHelper::sleep(sleepTime); + QtHelper::sleep(sleepTime); QByteArray data = com->readAll(); int dataLen = data.length(); if (dataLen <= 0) { @@ -314,9 +314,9 @@ void frmComTool::readData() if (isShow) { QString buffer; if (ui->ckHexReceive->isChecked()) { - buffer = QUIHelperData::byteArrayToHexStr(data); + buffer = QtHelperData::byteArrayToHexStr(data); } else { - //buffer = QUIHelperData::byteArrayToAsciiStr(data); + //buffer = QtHelperData::byteArrayToAsciiStr(data); buffer = QString::fromLocal8Bit(data); } @@ -372,9 +372,9 @@ void frmComTool::sendData(QString data) QByteArray buffer; if (ui->ckHexSend->isChecked()) { - buffer = QUIHelperData::hexStrToByteArray(data); + buffer = QtHelperData::hexStrToByteArray(data); } else { - buffer = QUIHelperData::asciiStrToByteArray(data); + buffer = QtHelperData::asciiStrToByteArray(data); } com->write(buffer); @@ -392,7 +392,7 @@ void frmComTool::saveData() QDateTime now = QDateTime::currentDateTime(); QString name = now.toString("yyyy-MM-dd-HH-mm-ss"); - QString fileName = QString("%1/%2.txt").arg(QUIHelper::appPath()).arg(name); + QString fileName = QString("%1/%2.txt").arg(QtHelper::appPath()).arg(name); QFile file(fileName); file.open(QFile::WriteOnly | QIODevice::Text); @@ -464,7 +464,7 @@ void frmComTool::on_btnStopShow_clicked() void frmComTool::on_btnData_clicked() { - QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg("send.txt"); + QString fileName = QString("%1/%2").arg(QtHelper::appPath()).arg("send.txt"); QFile file(fileName); if (!file.exists()) { return; @@ -558,14 +558,14 @@ void frmComTool::connectNet() void frmComTool::readDataNet() { if (socket->bytesAvailable() > 0) { - QUIHelper::sleep(AppConfig::SleepTime); + QtHelper::sleep(AppConfig::SleepTime); QByteArray data = socket->readAll(); QString buffer; if (ui->ckHexReceive->isChecked()) { - buffer = QUIHelperData::byteArrayToHexStr(data); + buffer = QtHelperData::byteArrayToHexStr(data); } else { - buffer = QUIHelperData::byteArrayToAsciiStr(data); + buffer = QtHelperData::byteArrayToAsciiStr(data); } append(5, buffer); diff --git a/tool/comtool/main.cpp b/tool/comtool/main.cpp index c338af6..42259f0 100644 --- a/tool/comtool/main.cpp +++ b/tool/comtool/main.cpp @@ -1,5 +1,5 @@ #include "frmcomtool.h" -#include "quihelper.h" +#include "qthelper.h" int main(int argc, char *argv[]) { @@ -14,9 +14,9 @@ int main(int argc, char *argv[]) a.setWindowIcon(QIcon(":/main.ico")); //设置编码以及加载中文翻译文件 - QUIHelper::initAll(); + QtHelper::initAll(); //读取配置文件 - AppConfig::ConfigFile = QString("%1/%2.ini").arg(QUIHelper::appPath()).arg(QUIHelper::appName()); + AppConfig::ConfigFile = QString("%1/%2.ini").arg(QtHelper::appPath()).arg(QtHelper::appName()); AppConfig::readConfig(); AppData::Intervals << "1" << "10" << "20" << "50" << "100" << "200" << "300" << "500" << "1000" << "1500" << "2000" << "3000" << "5000" << "10000"; @@ -24,9 +24,9 @@ int main(int argc, char *argv[]) AppData::readDeviceData(); frmComTool w; - w.setWindowTitle("串口调试助手 V2022 (QQ: 517216493 WX: feiyangqingyun)"); + w.setWindowTitle("串口调试助手 V2023 (QQ: 517216493 WX: feiyangqingyun)"); w.resize(900, 650); - QUIHelper::setFormInCenter(&w); + QtHelper::setFormInCenter(&w); w.show(); return a.exec(); diff --git a/tool/netserver/api/api.pri b/tool/netserver/api/api.pri index 335ed6d..d2cfd12 100644 --- a/tool/netserver/api/api.pri +++ b/tool/netserver/api/api.pri @@ -1,13 +1,13 @@ HEADERS += \ $$PWD/appconfig.h \ - $$PWD/quihelper.h \ - $$PWD/quihelperdata.h \ + $$PWD/qthelper.h \ + $$PWD/qthelperdata.h \ $$PWD/tcpserver1.h \ $$PWD/tcpserver2.h SOURCES += \ $$PWD/appconfig.cpp \ - $$PWD/quihelper.cpp \ - $$PWD/quihelperdata.cpp \ + $$PWD/qthelper.cpp \ + $$PWD/qthelperdata.cpp \ $$PWD/tcpserver1.cpp \ $$PWD/tcpserver2.cpp diff --git a/tool/netserver/api/appconfig.cpp b/tool/netserver/api/appconfig.cpp index 59be10c..51e749b 100644 --- a/tool/netserver/api/appconfig.cpp +++ b/tool/netserver/api/appconfig.cpp @@ -1,5 +1,5 @@ #include "appconfig.h" -#include "quihelper.h" +#include "qthelper.h" QString AppConfig::ConfigFile = "config.ini"; @@ -32,7 +32,7 @@ void AppConfig::readConfig() set.endGroup(); //配置文件不存在或者不全则重新生成 - if (!QUIHelper::checkIniFile(AppConfig::ConfigFile)) { + if (!QtHelper::checkIniFile(AppConfig::ConfigFile)) { writeConfig(); return; } diff --git a/tool/netserver/api/qthelper.cpp b/tool/netserver/api/qthelper.cpp new file mode 100644 index 0000000..1911055 --- /dev/null +++ b/tool/netserver/api/qthelper.cpp @@ -0,0 +1,1234 @@ +#include "qthelper.h" +#include "qnetworkinterface.h" +#include "qnetworkproxy.h" + +#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz")) + +QList QtHelper::getScreenRects(bool available) +{ + QList rects; +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + int screenCount = qApp->screens().count(); + QList screens = qApp->screens(); + for (int i = 0; i < screenCount; ++i) { + QScreen *screen = screens.at(i); + rects << (available ? screen->availableGeometry() : screen->geometry()); + } +#else + int screenCount = qApp->desktop()->screenCount(); + QDesktopWidget *desk = qApp->desktop(); + for (int i = 0; i < screenCount; ++i) { + rects << (available ? desk->availableGeometry(i) : desk->screenGeometry(i)); + } +#endif + return rects; +} + +int QtHelper::getScreenIndex() +{ + //需要对多个屏幕进行处理 + int screenIndex = 0; + QList rects = getScreenRects(false); + int count = rects.count(); + for (int i = 0; i < count; ++i) { + //找到当前鼠标所在屏幕 + QPoint pos = QCursor::pos(); + if (rects.at(i).contains(pos)) { + screenIndex = i; + break; + } + } + + return screenIndex; +} + +QRect QtHelper::getScreenRect(bool available) +{ + int screenIndex = getScreenIndex(); + QList rects = getScreenRects(available); + return rects.at(screenIndex); +} + +qreal QtHelper::getScreenRatio(bool devicePixel) +{ + qreal ratio = 1.0; + int screenIndex = getScreenIndex(); +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + QScreen *screen = qApp->screens().at(screenIndex); + if (devicePixel) { + //需要开启 AA_EnableHighDpiScaling 属性才能正常获取 + ratio = screen->devicePixelRatio() * 100; + } else { + ratio = screen->logicalDotsPerInch(); + } +#else + //Qt4不能动态识别缩放更改后的值 + ratio = qApp->desktop()->screen(screenIndex)->logicalDpiX(); +#endif + return ratio / 96; +} + +QRect QtHelper::checkCenterRect(QRect &rect, bool available) +{ + QRect deskRect = QtHelper::getScreenRect(available); + int formWidth = rect.width(); + int formHeight = rect.height(); + int deskWidth = deskRect.width(); + int deskHeight = deskRect.height(); + int formX = deskWidth / 2 - formWidth / 2 + deskRect.x(); + int formY = deskHeight / 2 - formHeight / 2; + rect = QRect(formX, formY, formWidth, formHeight); + return deskRect; +} + +int QtHelper::deskWidth() +{ + return getScreenRect().width(); +} + +int QtHelper::deskHeight() +{ + return getScreenRect().height(); +} + +QSize QtHelper::deskSize() +{ + return getScreenRect().size(); +} + +QWidget *QtHelper::centerBaseForm = 0; +void QtHelper::setFormInCenter(QWidget *form) +{ + int formWidth = form->width(); + int formHeight = form->height(); + + //如果=0表示采用系统桌面屏幕为参照 + QRect rect; + if (centerBaseForm == 0) { + rect = getScreenRect(); + } else { + rect = centerBaseForm->geometry(); + } + + int deskWidth = rect.width(); + int deskHeight = rect.height(); + QPoint movePoint(deskWidth / 2 - formWidth / 2 + rect.x(), deskHeight / 2 - formHeight / 2 + rect.y()); + form->move(movePoint); +} + +void QtHelper::showForm(QWidget *form) +{ + setFormInCenter(form); + form->show(); + + //判断宽高是否超过了屏幕分辨率,超过了则最大化显示 + //qDebug() << TIMEMS << form->size() << deskSize(); + if (form->width() + 20 > deskWidth() || form->height() + 50 > deskHeight()) { + QMetaObject::invokeMethod(form, "showMaximized", Qt::QueuedConnection); + } +} + +QString QtHelper::appName() +{ + //没有必要每次都获取,只有当变量为空时才去获取一次 + static QString name; + if (name.isEmpty()) { + name = qApp->applicationFilePath(); + //下面的方法主要为了过滤安卓的路径 lib程序名_armeabi-v7a/lib程序名_arm64-v8a + QStringList list = name.split("/"); + name = list.at(list.count() - 1).split(".").at(0); + name.replace("_armeabi-v7a", ""); + name.replace("_arm64-v8a", ""); + } + + return name; +} + +QString QtHelper::appPath() +{ + static QString path; + if (path.isEmpty()) { +#ifdef Q_OS_ANDROID + //默认安卓根目录 + path = "/storage/emulated/0"; + //带上程序名称作为目录 前面加个0方便排序 + path = path + "/0" + appName(); +#else + path = qApp->applicationDirPath(); +#endif + } + + return path; +} + +void QtHelper::getCurrentInfo(char *argv[], QString &path, QString &name) +{ + //必须用fromLocal8Bit保证中文路径正常 + QString argv0 = QString::fromLocal8Bit(argv[0]); + QFileInfo file(argv0); + path = file.path(); + name = file.baseName(); +} + +QString QtHelper::getIniValue(const QString &fileName, const QString &key) +{ + QString value; + QFile file(fileName); + if (file.open(QFile::ReadOnly | QFile::Text)) { + while (!file.atEnd()) { + QString line = file.readLine(); + if (line.startsWith(key)) { + line = line.replace("\n", ""); + line = line.trimmed(); + value = line.split("=").last(); + break; + } + } + } + return value; +} + +QString QtHelper::getIniValue(char *argv[], const QString &key, const QString &dir) +{ + QString path, name; + QtHelper::getCurrentInfo(argv, path, name); + QString fileName = QString("%1/%2%3.ini").arg(path).arg(dir).arg(name); + return getIniValue(fileName, key); +} + +QStringList QtHelper::getLocalIPs() +{ + static QStringList ips; + if (ips.count() == 0) { +#ifdef Q_OS_WASM + ips << "127.0.0.1"; +#else + QList netInterfaces = QNetworkInterface::allInterfaces(); + foreach (QNetworkInterface netInterface, netInterfaces) { + //移除虚拟机和抓包工具的虚拟网卡 + QString humanReadableName = netInterface.humanReadableName().toLower(); + if (humanReadableName.startsWith("vmware network adapter") || humanReadableName.startsWith("npcap loopback adapter")) { + continue; + } + + //过滤当前网络接口 + bool flag = (netInterface.flags() == (QNetworkInterface::IsUp | QNetworkInterface::IsRunning | QNetworkInterface::CanBroadcast | QNetworkInterface::CanMulticast)); + if (!flag) { + continue; + } + + QList addrs = netInterface.addressEntries(); + foreach (QNetworkAddressEntry addr, addrs) { + //只取出IPV4的地址 + if (addr.ip().protocol() != QAbstractSocket::IPv4Protocol) { + continue; + } + + QString ip4 = addr.ip().toString(); + if (ip4 != "127.0.0.1") { + ips << ip4; + } + } + } +#endif + } + + return ips; +} + +QList QtHelper::colors = QList(); +QList QtHelper::getColorList() +{ + //备用颜色集合 可以自行添加 + if (colors.count() == 0) { + colors << QColor(0, 176, 180) << QColor(0, 113, 193) << QColor(255, 192, 0); + colors << QColor(72, 103, 149) << QColor(185, 87, 86) << QColor(0, 177, 125); + colors << QColor(214, 77, 84) << QColor(71, 164, 233) << QColor(34, 163, 169); + colors << QColor(59, 123, 156) << QColor(162, 121, 197) << QColor(72, 202, 245); + colors << QColor(0, 150, 121) << QColor(111, 9, 176) << QColor(250, 170, 20); + } + + return colors; +} + +QStringList QtHelper::getColorNames() +{ + QList colors = getColorList(); + QStringList colorNames; + foreach (QColor color, colors) { + colorNames << color.name(); + } + return colorNames; +} + +QColor QtHelper::getRandColor() +{ + QList colors = getColorList(); + int index = getRandValue(0, colors.count(), true); + return colors.at(index); +} + +void QtHelper::initRand() +{ + //初始化随机数种子 + QTime t = QTime::currentTime(); + srand(t.msec() + t.second() * 1000); +} + +float QtHelper::getRandFloat(float min, float max) +{ + double diff = fabs(max - min); + double value = (double)(rand() % 100) / 100; + value = min + value * diff; + return value; +} + +double QtHelper::getRandValue(int min, int max, bool contansMin, bool contansMax) +{ + int value; +#if (QT_VERSION <= QT_VERSION_CHECK(5,10,0)) + //通用公式 a是起始值,n是整数的范围 + //int value = a + rand() % n; + if (contansMin) { + if (contansMax) { + value = min + 0 + (rand() % (max - min + 1)); + } else { + value = min + 0 + (rand() % (max - min + 0)); + } + } else { + if (contansMax) { + value = min + 1 + (rand() % (max - min + 0)); + } else { + value = min + 1 + (rand() % (max - min - 1)); + } + } +#else + if (contansMin) { + if (contansMax) { + value = QRandomGenerator::global()->bounded(min + 0, max + 1); + } else { + value = QRandomGenerator::global()->bounded(min + 0, max + 0); + } + } else { + if (contansMax) { + value = QRandomGenerator::global()->bounded(min + 1, max + 1); + } else { + value = QRandomGenerator::global()->bounded(min + 1, max + 0); + } + } +#endif + return value; +} + +QStringList QtHelper::getRandPoint(int count, float mainLng, float mainLat, float dotLng, float dotLat) +{ + //随机生成点坐标 + QStringList points; + for (int i = 0; i < count; ++i) { + //0.00881415 0.000442928 +#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0)) + float lngx = QRandomGenerator::global()->bounded(dotLng); + float latx = QRandomGenerator::global()->bounded(dotLat); +#else + float lngx = getRandFloat(dotLng / 10, dotLng); + float latx = getRandFloat(dotLat / 10, dotLat); +#endif + //需要先用精度转换成字符串 + QString lng2 = QString::number(mainLng + lngx, 'f', 8); + QString lat2 = QString::number(mainLat + latx, 'f', 8); + QString point = QString("%1,%2").arg(lng2).arg(lat2); + points << point; + } + + return points; +} + +int QtHelper::getRangeValue(int oldMin, int oldMax, int oldValue, int newMin, int newMax) +{ + return (((oldValue - oldMin) * (newMax - newMin)) / (oldMax - oldMin)) + newMin; +} + +QString QtHelper::getUuid() +{ + QString uuid = QUuid::createUuid().toString(); + uuid.replace("{", ""); + uuid.replace("}", ""); + return uuid; +} + +void QtHelper::checkPath(const QString &dirName) +{ + //相对路径需要补全完整路径 + QString path = dirName; + if (path.startsWith("./")) { + path.replace(".", ""); + path = QtHelper::appPath() + path; + } else if (!path.startsWith("/") && !path.contains(":/")) { + path = QtHelper::appPath() + "/" + path; + } + + //目录不存在则新建 + QDir dir(path); + if (!dir.exists()) { + dir.mkpath(path); + } +} + +void QtHelper::sleep(int msec, bool exec) +{ + if (msec <= 0) { + return; + } + + if (exec) { +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //阻塞方式延时(如果在主线程会卡住主界面) + QThread::msleep(msec); +#else + //非阻塞方式延时(不会卡住主界面/据说可能有问题) + QTime endTime = QTime::currentTime().addMSecs(msec); + while (QTime::currentTime() < endTime) { + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + } +#endif + } else { + //非阻塞方式延时(现在很多人推荐的方法) + QEventLoop loop; + QTimer::singleShot(msec, &loop, SLOT(quit())); + loop.exec(); + } +} + +void QtHelper::checkRun() +{ +#ifdef Q_OS_WIN + //延时1秒钟,等待程序释放完毕 + QtHelper::sleep(1000); + //创建共享内存,判断是否已经运行程序 + static QSharedMemory mem(QtHelper::appName()); + if (!mem.create(1)) { + QtHelper::showMessageBoxError("程序已运行, 软件将自动关闭!", 5, true); + exit(0); + } +#endif +} + +void QtHelper::setStyle() +{ + //打印下所有内置风格的名字 + qDebug() << TIMEMS << "QStyleFactory::keys" << QStyleFactory::keys(); + //设置内置风格 +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + qApp->setStyle("Fusion"); +#else + qApp->setStyle("Cleanlooks"); +#endif + + //设置指定颜色 + QPalette palette; + palette.setBrush(QPalette::Window, QColor("#F0F0F0")); + qApp->setPalette(palette); +} + +QFont QtHelper::addFont(const QString &fontFile, const QString &fontName) +{ + //判断图形字体是否存在,不存在则加入 + QFontDatabase fontDb; + if (!fontDb.families().contains(fontName)) { + int fontId = fontDb.addApplicationFont(fontFile); + QStringList listName = fontDb.applicationFontFamilies(fontId); + if (listName.count() == 0) { + qDebug() << QString("load %1 error").arg(fontName); + } + } + + //再次判断是否包含字体名称防止加载失败 + QFont font; + if (fontDb.families().contains(fontName)) { + font = QFont(fontName); +#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0)) + font.setHintingPreference(QFont::PreferNoHinting); +#endif + } + + return font; +} + +void QtHelper::setFont(int fontSize) +{ + //安卓套件在有些手机上默认字体不好看需要主动设置字体 + //网页套件需要主动加载中文字体才能正常显示中文 +#if (defined Q_OS_ANDROID) || (defined Q_OS_WASM) + QString fontFile = ":/font/DroidSansFallback.ttf"; + QString fontName = "Droid Sans Fallback"; + qApp->setFont(addFont(fontFile, fontName)); + return; +#endif + +#ifdef __arm__ + fontSize = 25; +#endif + + QFont font; + font.setFamily("MicroSoft Yahei"); + font.setPixelSize(fontSize); + qApp->setFont(font); +} + +void QtHelper::setCode(bool utf8) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //如果想要控制台打印信息中文正常就注释掉这个设置 + if (utf8) { + QTextCodec *codec = QTextCodec::codecForName("utf-8"); + QTextCodec::setCodecForLocale(codec); + } +#else +#if _MSC_VER + QTextCodec *codec = QTextCodec::codecForName("gbk"); +#else + QTextCodec *codec = QTextCodec::codecForName("utf-8"); +#endif + QTextCodec::setCodecForLocale(codec); + QTextCodec::setCodecForCStrings(codec); + QTextCodec::setCodecForTr(codec); +#endif +} + +void QtHelper::setTranslator(const QString &qmFile) +{ + //过滤下不存在的就不用设置了 + if (!QFile(qmFile).exists()) { + return; + } + + QTranslator *translator = new QTranslator(qApp); + if (translator->load(qmFile)) { + qApp->installTranslator(translator); + } +} + +#ifdef Q_OS_ANDROID +#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) +#include +#else +//Qt6中将相关类移到了core模块而且名字变了 +#include +#endif +#endif + +bool QtHelper::checkPermission(const QString &permission) +{ +#ifdef Q_OS_ANDROID +#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0) && QT_VERSION < QT_VERSION_CHECK(6,0,0)) + QtAndroid::PermissionResult result = QtAndroid::checkPermission(permission); + if (result == QtAndroid::PermissionResult::Denied) { + QtAndroid::requestPermissionsSync(QStringList() << permission); + result = QtAndroid::checkPermission(permission); + if (result == QtAndroid::PermissionResult::Denied) { + return false; + } + } +#else + QFuture result = QtAndroidPrivate::requestPermission(permission); + if (result.resultAt(0) == QtAndroidPrivate::PermissionResult::Denied) { + return false; + } +#endif +#endif + return true; +} + +void QtHelper::initAndroidPermission() +{ + //可以把所有要动态申请的权限都写在这里 + checkPermission("android.permission.CALL_PHONE"); + checkPermission("android.permission.SEND_SMS"); + checkPermission("android.permission.CAMERA"); + checkPermission("android.permission.READ_EXTERNAL_STORAGE"); + checkPermission("android.permission.WRITE_EXTERNAL_STORAGE"); + + checkPermission("android.permission.ACCESS_COARSE_LOCATION"); + checkPermission("android.permission.BLUETOOTH"); + checkPermission("android.permission.BLUETOOTH_SCAN"); + checkPermission("android.permission.BLUETOOTH_CONNECT"); + checkPermission("android.permission.BLUETOOTH_ADVERTISE"); +} + +void QtHelper::initAll(bool utf8, bool style, int fontSize) +{ + //初始化安卓权限 + QtHelper::initAndroidPermission(); + //初始化随机数种子 + QtHelper::initRand(); + //设置编码 + QtHelper::setCode(utf8); + //设置字体 + QtHelper::setFont(fontSize); + //设置样式风格 + if (style) { + QtHelper::setStyle(); + } + + //设置翻译文件支持多个 + QtHelper::setTranslator(":/qm/widgets.qm"); + QtHelper::setTranslator(":/qm/qt_zh_CN.qm"); + QtHelper::setTranslator(":/qm/designer_zh_CN.qm"); + + //设置不使用本地系统环境代理配置 + QNetworkProxyFactory::setUseSystemConfiguration(false); + //设置当前目录为程序可执行文件所在目录 + QDir::setCurrent(QtHelper::appPath()); + //Qt4中默认没有程序名称需要主动设置 +#if (QT_VERSION < QT_VERSION_CHECK(5,0,0)) + qApp->setApplicationName(QtHelper::appName()); +#endif +} + +void QtHelper::initMain(bool desktopSettingsAware, bool use96Dpi, bool logCritical) +{ +#ifdef Q_OS_WIN + //Qt6.5开始默认是ffmpeg后端但是不成熟需要换成系统的 + qputenv("QT_MEDIA_BACKEND", "windows"); +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //设置是否应用操作系统设置比如字体 + QApplication::setDesktopSettingsAware(desktopSettingsAware); +#endif + + bool highDpi = !use96Dpi; +#ifdef Q_OS_ANDROID + highDpi = true; +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,6,0)) + //开启高分屏缩放支持 + if (highDpi) { + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + } +#endif + +#ifdef Q_OS_WIN + if (use96Dpi) { + //Qt6中AA_Use96Dpi没效果必须下面方式设置强制指定缩放DPI + qputenv("QT_FONT_DPI", "96"); +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //不应用任何缩放 + QApplication::setAttribute(Qt::AA_Use96Dpi); +#endif + } +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) + //高分屏缩放策略 + QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor); +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //下面这行表示不打印Qt内部类的警告提示信息 + if (!logCritical) { + QLoggingCategory::setFilterRules("*.critical=false\n*.warning=false"); + } +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,4,0)) + //设置opengl共享上下文 + QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); +#endif +} + +void QtHelper::initOpenGL(quint8 type, bool checkCardEnable, bool checkVirtualSystem) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5,4,0)) + //设置opengl模式 AA_UseDesktopOpenGL(默认) AA_UseOpenGLES AA_UseSoftwareOpenGL + //在一些很旧的设备上或者对opengl支持很低的设备上需要使用AA_UseOpenGLES表示禁用硬件加速 + //如果开启的是AA_UseOpenGLES则无法使用硬件加速比如ffmpeg的dxva2 + if (type == 1) { + QApplication::setAttribute(Qt::AA_UseDesktopOpenGL); + } else if (type == 2) { + QApplication::setAttribute(Qt::AA_UseOpenGLES); + } else if (type == 3) { + QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); + } + + //检测显卡是否被禁用 + if (checkCardEnable && !isVideoCardEnable()) { + QApplication::setAttribute(Qt::AA_UseOpenGLES); + } + + //检测是否是虚拟机系统 + if (checkVirtualSystem && isVirtualSystem()) { + QApplication::setAttribute(Qt::AA_UseOpenGLES); + } +#endif +} + +QString QtHelper::doCmd(const QString &program, const QStringList &arguments, int timeout) +{ + QString result; +#ifndef Q_OS_WASM + QProcess p; + p.start(program, arguments); + p.waitForFinished(timeout); + result = QString::fromLocal8Bit(p.readAllStandardOutput()); + result.replace("\r", ""); + result.replace("\n", ""); + result = result.simplified(); + result = result.trimmed(); +#endif + return result; +} + +bool QtHelper::isVideoCardEnable() +{ + QString result; + bool videoCardEnable = true; + +#if defined(Q_OS_WIN) + QStringList args; + //wmic path win32_VideoController get name,Status + args << "path" << "win32_VideoController" << "get" << "name,Status"; + result = doCmd("wmic", args); +#endif + + //Name Status Intel(R) UHD Graphics 630 OK + //Name Status Intel(R) UHD Graphics 630 Error + if (result.contains("Error")) { + videoCardEnable = false; + } + + return videoCardEnable; +} + +bool QtHelper::isVirtualSystem() +{ + QString result; + bool virtualSystem = false; + +#if defined(Q_OS_WIN) + QStringList args; + //wmic computersystem get Model + args << "computersystem" << "get" << "Model"; + result = doCmd("wmic", args); +#elif defined(Q_OS_LINUX) + QStringList args; + //还有个命令需要root权限运行 dmidecode -s system-product-name 执行结果和win一样 + result = doCmd("lscpu", args); +#endif + + //Model MS-7C00 + //Model VMWare Virtual Platform + //Model VirtualBox Virtual Platform + //Model Alibaba Cloud ECS + if (result.contains("VMware") || result.contains("VirtualBox") || result.contains("Alibaba")) { + virtualSystem = true; + } + + return virtualSystem; +} + +QVector QtHelper::msgTypes = QVector() << 0 << 1 << 2 << 3 << 4; +QVector QtHelper::msgKeys = QVector() << QString::fromUtf8("发送") << QString::fromUtf8("接收") << QString::fromUtf8("解析") << QString::fromUtf8("错误") << QString::fromUtf8("提示"); +QVector QtHelper::msgColors = QVector() << QColor("#3BA372") << QColor("#EE6668") << QColor("#9861B4") << QColor("#FA8359") << QColor("#22A3A9"); +QString QtHelper::appendMsg(QTextEdit *textEdit, int type, const QString &data, int maxCount, int ¤tCount, bool clear, bool pause) +{ + if (clear) { + textEdit->clear(); + currentCount = 0; + return QString(); + } + + if (pause) { + return QString(); + } + + if (currentCount >= maxCount) { + textEdit->clear(); + currentCount = 0; + } + + //不同类型不同颜色显示 + QString strType; + int index = msgTypes.indexOf(type); + if (index >= 0) { + strType = msgKeys.at(index); + textEdit->setTextColor(msgColors.at(index)); + } + + //过滤回车换行符 + QString strData = data; + strData.replace("\r", ""); + strData.replace("\n", ""); + strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData); + textEdit->append(strData); + currentCount++; + return strData; +} + +void QtHelper::setFramelessForm(QWidget *widgetMain, bool tool, bool top, bool menu) +{ + widgetMain->setProperty("form", true); + widgetMain->setProperty("canMove", true); + + //根据设定逐个追加属性 +#ifdef __arm__ + widgetMain->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); +#else + widgetMain->setWindowFlags(Qt::FramelessWindowHint); +#endif + if (tool) { + widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::Tool); + } + if (top) { + widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowStaysOnTopHint); + } + if (menu) { + //如果是其他系统比如neokylin会产生系统边框 +#ifdef Q_OS_WIN + widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint); +#endif + } +} + +int QtHelper::showMessageBox(const QString &text, int type, int closeSec, bool exec) +{ + int result = 0; + if (type == 0) { + showMessageBoxInfo(text, closeSec, exec); + } else if (type == 1) { + showMessageBoxError(text, closeSec, exec); + } else if (type == 2) { + result = showMessageBoxQuestion(text); + } + + return result; +} + +void QtHelper::showMessageBoxInfo(const QString &text, int closeSec, bool exec) +{ + QMessageBox box(QMessageBox::Information, "提示", text); + box.setStandardButtons(QMessageBox::Yes); + box.setButtonText(QMessageBox::Yes, QString("确 定")); + box.exec(); + //QMessageBox::information(0, "提示", info, QMessageBox::Yes); +} + +void QtHelper::showMessageBoxError(const QString &text, int closeSec, bool exec) +{ + QMessageBox box(QMessageBox::Critical, "错误", text); + box.setStandardButtons(QMessageBox::Yes); + box.setButtonText(QMessageBox::Yes, QString("确 定")); + box.exec(); + //QMessageBox::critical(0, "错误", info, QMessageBox::Yes); +} + +int QtHelper::showMessageBoxQuestion(const QString &text) +{ + QMessageBox box(QMessageBox::Question, "询问", text); + box.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + box.setButtonText(QMessageBox::Yes, QString("确 定")); + box.setButtonText(QMessageBox::No, QString("取 消")); + return box.exec(); + //return QMessageBox::question(0, "询问", info, QMessageBox::Yes | QMessageBox::No); +} + +void QtHelper::initDialog(QFileDialog *dialog, const QString &title, const QString &acceptName, + const QString &dirName, bool native, int width, int height) +{ + //设置标题 + dialog->setWindowTitle(title); + //设置标签文本 + dialog->setLabelText(QFileDialog::Accept, acceptName); + dialog->setLabelText(QFileDialog::Reject, "取消(&C)"); + dialog->setLabelText(QFileDialog::LookIn, "查看"); + dialog->setLabelText(QFileDialog::FileName, "名称"); + dialog->setLabelText(QFileDialog::FileType, "类型"); + + //设置默认显示目录 + if (!dirName.isEmpty()) { + dialog->setDirectory(dirName); + } + + //设置对话框宽高 + if (width > 0 && height > 0) { +#ifdef Q_OS_ANDROID + bool horizontal = (QtHelper::deskWidth() > QtHelper::deskHeight()); + if (horizontal) { + width = QtHelper::deskWidth() / 2; + height = QtHelper::deskHeight() - 50; + } else { + width = QtHelper::deskWidth() - 10; + height = QtHelper::deskHeight() / 2; + } +#endif + dialog->setFixedSize(width, height); + } + + //设置是否采用本地对话框 + dialog->setOption(QFileDialog::DontUseNativeDialog, !native); + //设置只读可以取消右上角的新建按钮 + //dialog->setReadOnly(true); +} + +QString QtHelper::getDialogResult(QFileDialog *dialog) +{ + QString result; + if (dialog->exec() == QFileDialog::Accepted) { + result = dialog->selectedFiles().first(); + if (!result.contains(".")) { + //自动补全拓展名 保存文件(*.txt *.exe) + QString filter = dialog->selectedNameFilter(); + if (filter.contains("*.")) { + filter = filter.split("(").last(); + filter = filter.mid(0, filter.length() - 1); + //取出第一个作为拓展名 + if (!filter.contains("*.*")) { + filter = filter.split(" ").first(); + result = result + filter.mid(1, filter.length()); + } + } + } + } + return result; +} + +QString QtHelper::getOpenFileName(const QString &filter, const QString &dirName, const QString &fileName, + bool native, int width, int height) +{ + QFileDialog dialog; + initDialog(&dialog, "打开文件", "选择(&S)", dirName, native, width, height); + + //设置文件类型 + if (!filter.isEmpty()) { + dialog.setNameFilter(filter); + } + + //设置默认文件名称 + dialog.selectFile(fileName); + return getDialogResult(&dialog); +} + +QString QtHelper::getSaveFileName(const QString &filter, const QString &dirName, const QString &fileName, + bool native, int width, int height) +{ + QFileDialog dialog; + initDialog(&dialog, "保存文件", "保存(&S)", dirName, native, width, height); + + //设置文件类型 + if (!filter.isEmpty()) { + dialog.setNameFilter(filter); + } + + //设置默认文件名称 + dialog.selectFile(fileName); + //设置模态类型允许输入 + dialog.setWindowModality(Qt::WindowModal); + //设置置顶显示 + dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint); + return getDialogResult(&dialog); +} + +QString QtHelper::getExistingDirectory(const QString &dirName, bool native, int width, int height) +{ + QFileDialog dialog; + initDialog(&dialog, "选择目录", "选择(&S)", dirName, native, width, height); + dialog.setOption(QFileDialog::ReadOnly); + //设置只显示目录 +#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) + dialog.setFileMode(QFileDialog::DirectoryOnly); +#endif + dialog.setOption(QFileDialog::ShowDirsOnly); + return getDialogResult(&dialog); +} + +QString QtHelper::getXorEncryptDecrypt(const QString &value, char key) +{ + //矫正范围外的数据 + if (key < 0 || key >= 127) { + key = 127; + } + + //大概从5.9版本输出的加密密码字符串前面会加上 @String 字符 + QString result = value; + if (result.startsWith("@String")) { + result = result.mid(8, result.length() - 9); + } + + for (int i = 0; i < result.length(); ++i) { + result[i] = QChar(result.at(i).toLatin1() ^ key); + } + return result; +} + +quint8 QtHelper::getOrCode(const QByteArray &data) +{ + int len = data.length(); + quint8 result = 0; + for (int i = 0; i < len; ++i) { + result ^= data.at(i); + } + + return result; +} + +quint8 QtHelper::getCheckCode(const QByteArray &data) +{ + int len = data.length(); + quint8 temp = 0; + for (int i = 0; i < len; ++i) { + temp += data.at(i); + } + + return temp % 256; +} + +void QtHelper::initTableView(QTableView *tableView, int rowHeight, bool headVisible, bool edit, bool stretchLast) +{ + //设置弱属性用于应用qss特殊样式 + tableView->setProperty("model", true); + //取消自动换行 + tableView->setWordWrap(false); + //超出文本不显示省略号 + tableView->setTextElideMode(Qt::ElideNone); + //奇数偶数行颜色交替 + tableView->setAlternatingRowColors(false); + //垂直表头是否可见 + tableView->verticalHeader()->setVisible(headVisible); + //选中一行表头是否加粗 + tableView->horizontalHeader()->setHighlightSections(false); + //最后一行拉伸填充 + tableView->horizontalHeader()->setStretchLastSection(stretchLast); + //行标题最小宽度尺寸 + tableView->horizontalHeader()->setMinimumSectionSize(0); + //行标题最小高度,等同于和默认行高一致 + tableView->horizontalHeader()->setFixedHeight(rowHeight); + //默认行高 + tableView->verticalHeader()->setDefaultSectionSize(rowHeight); + //选中时一行整体选中 + tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + //只允许选择单个 + tableView->setSelectionMode(QAbstractItemView::SingleSelection); + + //表头不可单击 +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + tableView->horizontalHeader()->setSectionsClickable(false); +#else + tableView->horizontalHeader()->setClickable(false); +#endif + + //鼠标按下即进入编辑模式 + if (edit) { + tableView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::DoubleClicked); + } else { + tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + } +} + +void QtHelper::openFile(const QString &fileName, const QString &msg) +{ +#ifdef __arm__ + return; +#endif + //文件不存在则不用处理 + if (!QFile(fileName).exists()) { + return; + } + if (QtHelper::showMessageBoxQuestion(msg + "成功, 确定现在就打开吗?") == QMessageBox::Yes) { + QString url = QString("file:///%1").arg(fileName); + QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode)); + } +} + +bool QtHelper::checkIniFile(const QString &iniFile) +{ + //如果配置文件大小为0,则以初始值继续运行,并生成配置文件 + QFile file(iniFile); + if (file.size() == 0) { + return false; + } + + //如果配置文件不完整,则以初始值继续运行,并生成配置文件 + if (file.open(QFile::ReadOnly)) { + bool ok = true; + while (!file.atEnd()) { + QString line = file.readLine(); + line.replace("\r", ""); + line.replace("\n", ""); + QStringList list = line.split("="); + + if (list.count() == 2) { + QString key = list.at(0); + QString value = list.at(1); + if (value.isEmpty()) { + qDebug() << TIMEMS << "ini node no value" << key; + ok = false; + break; + } + } + } + + if (!ok) { + return false; + } + } else { + return false; + } + + return true; +} + +QString QtHelper::cutString(const QString &text, int len, int left, int right, bool file, const QString &mid) +{ + //如果指定了字符串分割则表示是文件名需要去掉拓展名 + QString result = text; + if (file && result.contains(".")) { + int index = result.lastIndexOf("."); + result = result.mid(0, index); + } + + //最终字符串格式为 前缀字符...后缀字符 + if (result.length() > len) { + result = QString("%1%2%3").arg(result.left(left)).arg(mid).arg(result.right(right)); + } + + return result; +} + +QRect QtHelper::getCenterRect(const QSize &imageSize, const QRect &widgetRect, int borderWidth, int scaleMode) +{ + QSize newSize = imageSize; + QSize widgetSize = widgetRect.size() - QSize(borderWidth * 1, borderWidth * 1); + + if (scaleMode == 0) { + if (newSize.width() > widgetSize.width() || newSize.height() > widgetSize.height()) { + newSize.scale(widgetSize, Qt::KeepAspectRatio); + } + } else if (scaleMode == 1) { + newSize.scale(widgetSize, Qt::KeepAspectRatio); + } else { + newSize = widgetSize; + } + + int x = widgetRect.center().x() - newSize.width() / 2; + int y = widgetRect.center().y() - newSize.height() / 2; + //不是2的倍数需要偏移1像素 + x += (x % 2 == 0 ? 1 : 0); + y += (y % 2 == 0 ? 1 : 0); + return QRect(x, y, newSize.width(), newSize.height()); +} + +void QtHelper::getScaledImage(QImage &image, const QSize &widgetSize, int scaleMode, bool fast) +{ + Qt::TransformationMode mode = fast ? Qt::FastTransformation : Qt::SmoothTransformation; + if (scaleMode == 0) { + if (image.width() > widgetSize.width() || image.height() > widgetSize.height()) { + image = image.scaled(widgetSize, Qt::KeepAspectRatio, mode); + } + } else if (scaleMode == 1) { + image = image.scaled(widgetSize, Qt::KeepAspectRatio, mode); + } else { + image = image.scaled(widgetSize, Qt::IgnoreAspectRatio, mode); + } +} + +QString QtHelper::getTimeString(qint64 time) +{ + time = time / 1000; + QString min = QString("%1").arg(time / 60, 2, 10, QChar('0')); + QString sec = QString("%2").arg(time % 60, 2, 10, QChar('0')); + return QString("%1:%2").arg(min).arg(sec); +} + +QString QtHelper::getTimeString(QElapsedTimer timer) +{ + return QString::number((float)timer.elapsed() / 1000, 'f', 3); +} + +QString QtHelper::getSizeString(quint64 size) +{ + float num = size; + QStringList list; + list << "KB" << "MB" << "GB" << "TB"; + + QString unit("bytes"); + QStringListIterator i(list); + while (num >= 1024.0 && i.hasNext()) { + unit = i.next(); + num /= 1024.0; + } + + return QString("%1 %2").arg(QString::number(num, 'f', 2)).arg(unit); +} + +//setSystemDateTime("2022", "07", "01", "12", "22", "55"); +void QtHelper::setSystemDateTime(const QString &year, const QString &month, const QString &day, const QString &hour, const QString &min, const QString &sec) +{ +#ifdef Q_OS_WIN + QProcess p(0); + //先设置日期 + p.start("cmd"); + p.waitForStarted(); + p.write(QString("date %1-%2-%3\n").arg(year).arg(month).arg(day).toLatin1()); + p.closeWriteChannel(); + p.waitForFinished(1000); + p.close(); + //再设置时间 + p.start("cmd"); + p.waitForStarted(); + p.write(QString("time %1:%2:%3.00\n").arg(hour).arg(min).arg(sec).toLatin1()); + p.closeWriteChannel(); + p.waitForFinished(1000); + p.close(); +#else + QString cmd = QString("date %1%2%3%4%5.%6").arg(month).arg(day).arg(hour).arg(min).arg(year).arg(sec); + //设置日期时间 + system(cmd.toLatin1()); + //硬件时钟同步 + system("hwclock -w"); +#endif +} + +void QtHelper::runWithSystem(bool autoRun) +{ + QtHelper::runWithSystem(qApp->applicationName(), qApp->applicationFilePath(), autoRun); +} + +void QtHelper::runWithSystem(const QString &fileName, const QString &filePath, bool autoRun) +{ +#ifdef Q_OS_WIN + //要转换成本地文件路径(不启动则文件路径为空即可) + QSettings reg("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat); + reg.setValue(fileName, autoRun ? QDir::toNativeSeparators(filePath) : ""); +#endif +} + +void QtHelper::runBin(const QString &path, const QString &name) +{ +#ifdef Q_OS_WIN + QString cmd1 = "tasklist"; + QString cmd2 = QString("%1/%2.exe").arg(path).arg(name); +#else + QString cmd1 = "ps -aux"; + QString cmd2 = QString("%1/%2").arg(path).arg(name); +#endif + +#ifndef Q_OS_WASM + QProcess p; + p.start(cmd1); + if (p.waitForFinished()) { + QString result = p.readAll(); + if (result.contains(name)) { + return; + } + } + + //加上引号可以兼容打开带空格的目录(Program Files) + if (cmd2.contains(" ")) { + cmd2 = "\"" + cmd2 + "\""; + } + + //QProcess::execute(cmd2); + QProcess::startDetached(cmd2); +#endif +} diff --git a/tool/comtool/api/quihelper.h b/tool/netserver/api/qthelper.h similarity index 55% rename from tool/comtool/api/quihelper.h rename to tool/netserver/api/qthelper.h index 759b1a7..6562b43 100644 --- a/tool/comtool/api/quihelper.h +++ b/tool/netserver/api/qthelper.h @@ -1,14 +1,19 @@ -#ifndef QUIHELPER2_H -#define QUIHELPER2_H +#ifndef QTHELPER_H +#define QTHELPER_H #include "head.h" -class QUIHelper +class QtHelper { public: - //获取当前鼠标所在屏幕索引+尺寸 + //获取所有屏幕区域/当前鼠标所在屏幕索引/区域尺寸/缩放系数 + static QList getScreenRects(bool available = true); static int getScreenIndex(); static QRect getScreenRect(bool available = true); + static qreal getScreenRatio(bool devicePixel = false); + + //矫正当前鼠标所在屏幕居中尺寸 + static QRect checkCenterRect(QRect &rect, bool available = true); //获取桌面宽度高度+居中显示 static int deskWidth(); @@ -21,10 +26,16 @@ public: static void setFormInCenter(QWidget *form); static void showForm(QWidget *form); - //程序文件名称+当前所在路径 + //程序文件名称和当前所在路径 static QString appName(); static QString appPath(); + //程序最前面获取应用程序路径和名称 + static void getCurrentInfo(char *argv[], QString &path, QString &name); + //程序最前面读取配置文件节点的值 + static QString getIniValue(const QString &fileName, const QString &key); + static QString getIniValue(char *argv[], const QString &key, const QString &dir = QString()); + //获取本地网卡IP集合 static QStringList getLocalIPs(); @@ -43,13 +54,17 @@ public: static double getRandValue(int min, int max, bool contansMin = false, bool contansMax = false); //获取范围值随机经纬度集合 static QStringList getRandPoint(int count, float mainLng, float mainLat, float dotLng, float dotLat); + //根据旧的范围值和值计算新的范围值对应的值 + static int getRangeValue(int oldMin, int oldMax, int oldValue, int newMin, int newMax); //获取uuid static QString getUuid(); - //可执行文件目录下新建目录 - static void newDir(const QString &dirName); - //延时 - static void sleep(int msec); + //校验目录 + static void checkPath(const QString &dirName); + //通用延时函数(支持Qt4 Qt5 Qt6) + static void sleep(int msec, bool exec = true); + //检查程序是否已经运行 + static void checkRun(); //设置Qt自带样式 static void setStyle(); @@ -61,10 +76,24 @@ public: //设置翻译文件 static void setTranslator(const QString &qmFile); + //动态设置权限 + static bool checkPermission(const QString &permission); + //申请安卓权限 + static void initAndroidPermission(); + //一次性设置所有包括编码样式字体等 static void initAll(bool utf8 = true, bool style = true, int fontSize = 13); //初始化main函数最前面执行的一段代码 - static void initMain(bool on = true); + static void initMain(bool desktopSettingsAware = false, bool use96Dpi = true, bool logCritical = true); + //初始化opengl类型(1=AA_UseDesktopOpenGL 2=AA_UseOpenGLES 3=AA_UseSoftwareOpenGL) + static void initOpenGL(quint8 type = 0, bool checkCardEnable = false, bool checkVirtualSystem = false); + + //执行命令行返回执行结果 + static QString doCmd(const QString &program, const QStringList &arguments, int timeout = 1000); + //获取显卡是否被禁用 + static bool isVideoCardEnable(); + //获取是否在虚拟机环境 + static bool isVirtualSystem(); //插入消息 static QVector msgTypes; @@ -78,13 +107,13 @@ public: static void setFramelessForm(QWidget *widgetMain, bool tool = false, bool top = false, bool menu = true); //弹出框 - static int showMessageBox(const QString &info, int type = 0, int closeSec = 0, bool exec = false); + static int showMessageBox(const QString &text, int type = 0, int closeSec = 0, bool exec = false); //弹出消息框 - static void showMessageBoxInfo(const QString &info, int closeSec = 0, bool exec = false); + static void showMessageBoxInfo(const QString &text, int closeSec = 0, bool exec = false); //弹出错误框 - static void showMessageBoxError(const QString &info, int closeSec = 0, bool exec = false); + static void showMessageBoxError(const QString &text, int closeSec = 0, bool exec = false); //弹出询问框 - static int showMessageBoxQuestion(const QString &info); + static int showMessageBoxQuestion(const QString &text); //为什么还要自定义对话框因为可控宽高和汉化对应文本等 //初始化对话框文本 @@ -109,9 +138,9 @@ public: //异或加密-只支持字符,如果是中文需要将其转换base64编码 static QString getXorEncryptDecrypt(const QString &value, char key); //异或校验 - static uchar getOrCode(const QByteArray &data); + static quint8 getOrCode(const QByteArray &data); //计算校验码 - static uchar getCheckCode(const QByteArray &data); + static quint8 getCheckCode(const QByteArray &data); //初始化表格 static void initTableView(QTableView *tableView, int rowHeight = 25, @@ -124,7 +153,28 @@ public: static bool checkIniFile(const QString &iniFile); //首尾截断字符串显示 - static QString cutString(const QString &text, int len, int left, int right, const QString &mid = "..."); + static QString cutString(const QString &text, int len, int left, int right, bool file, const QString &mid = "..."); + + //传入图片尺寸和窗体区域及边框大小返回居中区域(scaleMode: 0-自动调整 1-等比缩放 2-拉伸填充) + static QRect getCenterRect(const QSize &imageSize, const QRect &widgetRect, int borderWidth = 2, int scaleMode = 0); + //传入图片尺寸和窗体尺寸及缩放策略返回合适尺寸(scaleMode: 0-自动调整 1-等比缩放 2-拉伸填充) + static void getScaledImage(QImage &image, const QSize &widgetSize, int scaleMode = 0, bool fast = true); + + //毫秒数转时间 00:00 + static QString getTimeString(qint64 time); + //用时时间转秒数 + static QString getTimeString(QElapsedTimer timer); + //文件大小转 KB MB GB TB + static QString getSizeString(quint64 size); + + //设置系统时间 + static void setSystemDateTime(const QString &year, const QString &month, const QString &day, + const QString &hour, const QString &min, const QString &sec); + //设置开机自启动 + static void runWithSystem(bool autoRun = true); + static void runWithSystem(const QString &fileName, const QString &filePath, bool autoRun = true); + //启动运行程序(已经在运行则不启动) + static void runBin(const QString &path, const QString &name); }; -#endif // QUIHELPER2_H +#endif // QTHELPER_H diff --git a/tool/comtool/api/quihelperdata.cpp b/tool/netserver/api/qthelperdata.cpp similarity index 66% rename from tool/comtool/api/quihelperdata.cpp rename to tool/netserver/api/qthelperdata.cpp index 62b7f05..5f26ee5 100644 --- a/tool/comtool/api/quihelperdata.cpp +++ b/tool/netserver/api/qthelperdata.cpp @@ -1,29 +1,29 @@ -#include "quihelperdata.h" -#include "quihelper.h" +#include "qthelperdata.h" +#include "qthelper.h" -int QUIHelperData::strHexToDecimal(const QString &strHex) +int QtHelperData::strHexToDecimal(const QString &strHex) { bool ok; return strHex.toInt(&ok, 16); } -int QUIHelperData::strDecimalToDecimal(const QString &strDecimal) +int QtHelperData::strDecimalToDecimal(const QString &strDecimal) { bool ok; return strDecimal.toInt(&ok, 10); } -int QUIHelperData::strBinToDecimal(const QString &strBin) +int QtHelperData::strBinToDecimal(const QString &strBin) { bool ok; return strBin.toInt(&ok, 2); } -QString QUIHelperData::strHexToStrBin(const QString &strHex) +QString QtHelperData::strHexToStrBin(const QString &strHex) { - uchar decimal = strHexToDecimal(strHex); + quint8 decimal = strHexToDecimal(strHex); QString bin = QString::number(decimal, 2); - uchar len = bin.length(); + quint8 len = bin.length(); if (len < 8) { for (int i = 0; i < 8 - len; ++i) { @@ -34,10 +34,10 @@ QString QUIHelperData::strHexToStrBin(const QString &strHex) return bin; } -QString QUIHelperData::decimalToStrBin1(int decimal) +QString QtHelperData::decimalToStrBin1(int decimal) { QString bin = QString::number(decimal, 2); - uchar len = bin.length(); + quint8 len = bin.length(); if (len <= 8) { for (int i = 0; i < 8 - len; ++i) { bin = "0" + bin; @@ -47,10 +47,10 @@ QString QUIHelperData::decimalToStrBin1(int decimal) return bin; } -QString QUIHelperData::decimalToStrBin2(int decimal) +QString QtHelperData::decimalToStrBin2(int decimal) { QString bin = QString::number(decimal, 2); - uchar len = bin.length(); + quint8 len = bin.length(); if (len <= 16) { for (int i = 0; i < 16 - len; ++i) { bin = "0" + bin; @@ -60,7 +60,7 @@ QString QUIHelperData::decimalToStrBin2(int decimal) return bin; } -QString QUIHelperData::decimalToStrHex(int decimal) +QString QtHelperData::decimalToStrHex(int decimal) { QString temp = QString::number(decimal, 16); if (temp.length() == 1) { @@ -70,105 +70,80 @@ QString QUIHelperData::decimalToStrHex(int decimal) return temp; } -QByteArray QUIHelperData::intToByte(int data) +QByteArray QtHelperData::intToByte(int data, bool reverse) { + quint8 data1 = (quint8)(0x000000ff & data); + quint8 data2 = (quint8)((0x0000ff00 & data) >> 8); + quint8 data3 = (quint8)((0x00ff0000 & data) >> 16); + quint8 data4 = (quint8)((0xff000000 & data) >> 24); + QByteArray result; result.resize(4); - result[3] = (uchar)(0x000000ff & data); - result[2] = (uchar)((0x0000ff00 & data) >> 8); - result[1] = (uchar)((0x00ff0000 & data) >> 16); - result[0] = (uchar)((0xff000000 & data) >> 24); + if (reverse) { + result[0] = data1; + result[1] = data2; + result[2] = data3; + result[3] = data4; + } else { + result[0] = data4; + result[1] = data3; + result[2] = data2; + result[3] = data1; + } return result; } -QByteArray QUIHelperData::intToByteRec(int data) +int QtHelperData::byteToInt(const QByteArray &data, bool reverse) { - QByteArray result; - result.resize(4); - result[0] = (uchar)(0x000000ff & data); - result[1] = (uchar)((0x0000ff00 & data) >> 8); - result[2] = (uchar)((0x00ff0000 & data) >> 16); - result[3] = (uchar)((0xff000000 & data) >> 24); + int result = 0; + if (reverse) { + result = data.at(0) & 0x000000ff; + result |= ((data.at(1) << 8) & 0x0000ff00); + result |= ((data.at(2) << 16) & 0x00ff0000); + result |= ((data.at(3) << 24) & 0xff000000); + } else { + result = data.at(3) & 0x000000ff; + result |= ((data.at(2) << 8) & 0x0000ff00); + result |= ((data.at(1) << 16) & 0x00ff0000); + result |= ((data.at(0) << 24) & 0xff000000); + } return result; } -int QUIHelperData::byteToInt(const QByteArray &data) +QByteArray QtHelperData::ushortToByte(int data, bool reverse) { - int i = data.at(3) & 0x000000ff; - i |= ((data.at(2) << 8) & 0x0000ff00); - i |= ((data.at(1) << 16) & 0x00ff0000); - i |= ((data.at(0) << 24) & 0xff000000); - return i; -} + quint8 data1 = (quint8)(0x000000ff & data); + quint8 data2 = (quint8)((0x0000ff00 & data) >> 8); -int QUIHelperData::byteToIntRec(const QByteArray &data) -{ - int i = data.at(0) & 0x000000ff; - i |= ((data.at(1) << 8) & 0x0000ff00); - i |= ((data.at(2) << 16) & 0x00ff0000); - i |= ((data.at(3) << 24) & 0xff000000); - return i; -} - -quint32 QUIHelperData::byteToUInt(const QByteArray &data) -{ - quint32 i = data.at(3) & 0x000000ff; - i |= ((data.at(2) << 8) & 0x0000ff00); - i |= ((data.at(1) << 16) & 0x00ff0000); - i |= ((data.at(0) << 24) & 0xff000000); - return i; -} - -quint32 QUIHelperData::byteToUIntRec(const QByteArray &data) -{ - quint32 i = data.at(0) & 0x000000ff; - i |= ((data.at(1) << 8) & 0x0000ff00); - i |= ((data.at(2) << 16) & 0x00ff0000); - i |= ((data.at(3) << 24) & 0xff000000); - return i; -} - -QByteArray QUIHelperData::ushortToByte(ushort data) -{ QByteArray result; result.resize(2); - result[1] = (uchar)(0x000000ff & data); - result[0] = (uchar)((0x0000ff00 & data) >> 8); + if (reverse) { + result[0] = data1; + result[1] = data2; + } else { + result[0] = data2; + result[1] = data1; + } return result; } -QByteArray QUIHelperData::ushortToByteRec(ushort data) +int QtHelperData::byteToShort(const QByteArray &data, bool reverse) { - QByteArray result; - result.resize(2); - result[0] = (uchar)(0x000000ff & data); - result[1] = (uchar)((0x0000ff00 & data) >> 8); + int result = 0; + if (reverse) { + result = data.at(0) & 0x000000ff; + result |= ((data.at(1) << 8) & 0x0000ff00); + } else { + result = data.at(1) & 0x000000ff; + result |= ((data.at(0) << 8) & 0x0000ff00); + } + if (result >= 32768) { + result = result - 65536; + } return result; } -int QUIHelperData::byteToUShort(const QByteArray &data) -{ - int i = data.at(1) & 0x000000FF; - i |= ((data.at(0) << 8) & 0x0000FF00); - if (i >= 32768) { - i = i - 65536; - } - - return i; -} - -int QUIHelperData::byteToUShortRec(const QByteArray &data) -{ - int i = data.at(0) & 0x000000FF; - i |= ((data.at(1) << 8) & 0x0000FF00); - if (i >= 32768) { - i = i - 65536; - } - - return i; -} - -QString QUIHelperData::getValue(quint8 value) +QString QtHelperData::getValue(quint8 value) { QString result = QString::number(value); if (result.length() <= 1) { @@ -177,7 +152,36 @@ QString QUIHelperData::getValue(quint8 value) return result; } -QString QUIHelperData::getXorEncryptDecrypt(const QString &value, char key) +QString QtHelperData::trimmed(const QString &text, int type) +{ + QString temp = text; + QString pattern; + if (type == -1) { + pattern = "^ +\\s*"; + } else if (type == 0) { + pattern = "\\s"; + //temp.replace(" ", ""); + } else if (type == 1) { + pattern = "\\s* +$"; + } else if (type == 2) { + temp = temp.trimmed(); + } else if (type == 3) { + temp = temp.simplified(); + } + + //调用正则表达式移除空格 + if (!pattern.isEmpty()) { +#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0)) + temp.remove(QRegularExpression(pattern)); +#else + temp.remove(QRegExp(pattern)); +#endif + } + + return temp; +} + +QString QtHelperData::getXorEncryptDecrypt(const QString &value, char key) { //矫正范围外的数据 if (key < 0 || key >= 127) { @@ -190,17 +194,16 @@ QString QUIHelperData::getXorEncryptDecrypt(const QString &value, char key) result = result.mid(8, result.length() - 9); } - int count = result.count(); - for (int i = 0; i < count; ++i) { + for (int i = 0; i < result.length(); ++i) { result[i] = QChar(result.at(i).toLatin1() ^ key); } return result; } -uchar QUIHelperData::getOrCode(const QByteArray &data) +quint8 QtHelperData::getOrCode(const QByteArray &data) { int len = data.length(); - uchar result = 0; + quint8 result = 0; for (int i = 0; i < len; ++i) { result ^= data.at(i); } @@ -208,17 +211,27 @@ uchar QUIHelperData::getOrCode(const QByteArray &data) return result; } -uchar QUIHelperData::getCheckCode(const QByteArray &data) +quint8 QtHelperData::getCheckCode(const QByteArray &data) { int len = data.length(); - uchar temp = 0; - for (uchar i = 0; i < len; ++i) { + quint8 temp = 0; + for (int i = 0; i < len; ++i) { temp += data.at(i); } return temp % 256; } +void QtHelperData::getFullData(QByteArray &buffer) +{ + //计算校验码 + quint8 checkCode = getCheckCode(buffer); + //尾部插入校验码 + buffer.append(checkCode); + //头部插入固定帧头 + buffer.insert(0, 0x16); +} + //函数功能:计算CRC16 //参数1:*data 16位CRC校验数据, //参数2:len 数据流长度 @@ -226,7 +239,7 @@ uchar QUIHelperData::getCheckCode(const QByteArray &data) //参数4:table 16位CRC查找表 //正序CRC计算 -quint16 QUIHelperData::getCrc16(quint8 *data, int len, quint16 init, const quint16 *table) +quint16 QtHelperData::getCrc16(quint8 *data, int len, quint16 init, const quint16 *table) { quint16 crc_16 = init; quint8 temp; @@ -239,7 +252,7 @@ quint16 QUIHelperData::getCrc16(quint8 *data, int len, quint16 init, const quint } //逆序CRC计算 -quint16 QUIHelperData::getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table) +quint16 QtHelperData::getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table) { quint16 crc_16 = init; quint8 temp; @@ -252,7 +265,7 @@ quint16 QUIHelperData::getCrc16Rec(quint8 *data, int len, quint16 init, const qu } //Modbus CRC16校验 -quint16 QUIHelperData::getModbus16(quint8 *data, int len) +quint16 QtHelperData::getModbus16(quint8 *data, int len) { //MODBUS CRC-16表 8005 逆序 const quint16 table_16[256] = { @@ -294,14 +307,14 @@ quint16 QUIHelperData::getModbus16(quint8 *data, int len) } //CRC16校验 -QByteArray QUIHelperData::getCrcCode(const QByteArray &data) +QByteArray QtHelperData::getCrcCode(const QByteArray &data) { quint16 result = getModbus16((quint8 *)data.data(), data.length()); - return QUIHelperData::ushortToByteRec(result); + return QtHelperData::ushortToByte(result, true); } static QMap listChar; -void QUIHelperData::initAscii() +void QtHelperData::initAscii() { //0x20为空格,空格以下都是不可见字符 if (listChar.count() == 0) { @@ -342,13 +355,13 @@ void QUIHelperData::initAscii() } } -QString QUIHelperData::byteArrayToAsciiStr(const QByteArray &data) +QString QtHelperData::byteArrayToAsciiStr(const QByteArray &data) { //先初始化字符表 initAscii(); QString temp; - int len = data.size(); + int len = data.length(); for (int i = 0; i < len; ++i) { char byte = data.at(i); QString value = listChar.value(byte); @@ -366,7 +379,7 @@ QString QUIHelperData::byteArrayToAsciiStr(const QByteArray &data) return temp.trimmed(); } -QByteArray QUIHelperData::asciiStrToByteArray(const QString &data) +QByteArray QtHelperData::asciiStrToByteArray(const QString &data) { //先初始化字符表 initAscii(); @@ -388,14 +401,14 @@ QByteArray QUIHelperData::asciiStrToByteArray(const QString &data) } //可能是纯字符串不带控制字符 - if (buffer.size() == 0) { + if (buffer.length() == 0) { buffer = data.toUtf8(); } return buffer; } -char QUIHelperData::hexStrToChar(char data) +char QtHelperData::hexStrToChar(char data) { if ((data >= '0') && (data <= '9')) { return data - 0x30; @@ -408,7 +421,7 @@ char QUIHelperData::hexStrToChar(char data) } } -QByteArray QUIHelperData::hexStrToByteArray(const QString &data) +QByteArray QtHelperData::hexStrToByteArray(const QString &data) { QByteArray senddata; int hexdata, lowhexdata; @@ -448,7 +461,7 @@ QByteArray QUIHelperData::hexStrToByteArray(const QString &data) return senddata; } -QString QUIHelperData::byteArrayToHexStr(const QByteArray &data) +QString QtHelperData::byteArrayToHexStr(const QByteArray &data) { QString temp = ""; QString hex = data.toHex(); diff --git a/tool/nettool/api/quihelperdata.h b/tool/netserver/api/qthelperdata.h similarity index 65% rename from tool/nettool/api/quihelperdata.h rename to tool/netserver/api/qthelperdata.h index b5e3815..0f649c3 100644 --- a/tool/nettool/api/quihelperdata.h +++ b/tool/netserver/api/qthelperdata.h @@ -1,9 +1,9 @@ -#ifndef QUIHELPERDATA_H -#define QUIHELPERDATA_H +#ifndef QTHELPERDATA_H +#define QTHELPERDATA_H #include -class QUIHelperData +class QtHelperData { public: //16进制字符串转10进制 @@ -22,33 +22,28 @@ public: //10进制转16进制字符串,补零. static QString decimalToStrHex(int decimal); - //int转字节数组 - static QByteArray intToByte(int data); - static QByteArray intToByteRec(int data); + //int和字节数组互转 + static QByteArray intToByte(int data, bool reverse = false); + static int byteToInt(const QByteArray &data, bool reverse = false); - //字节数组转int - static int byteToInt(const QByteArray &data); - static int byteToIntRec(const QByteArray &data); - static quint32 byteToUInt(const QByteArray &data); - static quint32 byteToUIntRec(const QByteArray &data); - - //ushort转字节数组 - static QByteArray ushortToByte(ushort data); - static QByteArray ushortToByteRec(ushort data); - - //字节数组转ushort - static int byteToUShort(const QByteArray &data); - static int byteToUShortRec(const QByteArray &data); + //ushort和字节数组互转 + static QByteArray ushortToByte(int data, bool reverse = false); + static int byteToShort(const QByteArray &data, bool reverse = false); //字符串补全 static QString getValue(quint8 value); + //字符串去空格 -1=移除左侧空格 0=移除所有空格 1=移除右侧空格 2=移除首尾空格 3=首尾清除中间留一个空格 + static QString trimmed(const QString &text, int type); //异或加密-只支持字符,如果是中文需要将其转换base64编码 static QString getXorEncryptDecrypt(const QString &value, char key); //异或校验 - static uchar getOrCode(const QByteArray &data); - //计算校验码 - static uchar getCheckCode(const QByteArray &data); + static quint8 getOrCode(const QByteArray &data); + + //公司专用-计算校验码 + static quint8 getCheckCode(const QByteArray &data); + //公司专用-加上桢头和校验码完整数据 + static void getFullData(QByteArray &buffer); //CRC校验 static quint16 getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table); @@ -67,4 +62,4 @@ public: static QString byteArrayToHexStr(const QByteArray &data); }; -#endif // QUIHELPERDATA_H +#endif // QTHELPERDATA_H diff --git a/tool/netserver/api/quihelper.cpp b/tool/netserver/api/quihelper.cpp deleted file mode 100644 index 788147d..0000000 --- a/tool/netserver/api/quihelper.cpp +++ /dev/null @@ -1,818 +0,0 @@ -#include "quihelper.h" -#include "qnetworkinterface.h" -#include "qnetworkproxy.h" - -#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz")) -int QUIHelper::getScreenIndex() -{ - //需要对多个屏幕进行处理 - int screenIndex = 0; -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - int screenCount = qApp->screens().count(); -#else - int screenCount = qApp->desktop()->screenCount(); -#endif - - if (screenCount > 1) { - //找到当前鼠标所在屏幕 - QPoint pos = QCursor::pos(); - for (int i = 0; i < screenCount; ++i) { -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - if (qApp->screens().at(i)->geometry().contains(pos)) { -#else - if (qApp->desktop()->screenGeometry(i).contains(pos)) { -#endif - screenIndex = i; - break; - } - } - } - return screenIndex; -} - -QRect QUIHelper::getScreenRect(bool available) -{ - QRect rect; - int screenIndex = QUIHelper::getScreenIndex(); - if (available) { -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - rect = qApp->screens().at(screenIndex)->availableGeometry(); -#else - rect = qApp->desktop()->availableGeometry(screenIndex); -#endif - } else { -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - rect = qApp->screens().at(screenIndex)->geometry(); -#else - rect = qApp->desktop()->screenGeometry(screenIndex); -#endif - } - return rect; -} - -int QUIHelper::deskWidth() -{ - return getScreenRect().width(); -} - -int QUIHelper::deskHeight() -{ - return getScreenRect().height(); -} - -QSize QUIHelper::deskSize() -{ - return getScreenRect().size(); -} - -QWidget *QUIHelper::centerBaseForm = 0; -void QUIHelper::setFormInCenter(QWidget *form) -{ - int formWidth = form->width(); - int formHeight = form->height(); - - //如果=0表示采用系统桌面屏幕为参照 - QRect rect; - if (centerBaseForm == 0) { - rect = getScreenRect(); - } else { - rect = centerBaseForm->geometry(); - } - - int deskWidth = rect.width(); - int deskHeight = rect.height(); - QPoint movePoint(deskWidth / 2 - formWidth / 2 + rect.x(), deskHeight / 2 - formHeight / 2 + rect.y()); - form->move(movePoint); -} - -void QUIHelper::showForm(QWidget *form) -{ - setFormInCenter(form); - form->show(); - - //判断宽高是否超过了屏幕分辨率,超过了则最大化显示 - //qDebug() << TIMEMS << form->size() << deskSize(); - if (form->width() + 20 > deskWidth() || form->height() + 50 > deskHeight()) { - QMetaObject::invokeMethod(form, "showMaximized", Qt::QueuedConnection); - } -} - -QString QUIHelper::appName() -{ - //没有必要每次都获取,只有当变量为空时才去获取一次 - static QString name; - if (name.isEmpty()) { - name = qApp->applicationFilePath(); - //下面的方法主要为了过滤安卓的路径 lib程序名_armeabi-v7a - QStringList list = name.split("/"); - name = list.at(list.count() - 1).split(".").at(0); - name.replace("_armeabi-v7a", ""); - } - - return name; -} - -QString QUIHelper::appPath() -{ - static QString path; - if (path.isEmpty()) { -#ifdef Q_OS_ANDROID - //默认安卓根目录 - path = "/storage/emulated/0"; - //带上程序名称作为目录 前面加个0方便排序 - path = path + "/0" + appName(); -#else - path = qApp->applicationDirPath(); -#endif - } - - return path; -} - -QStringList QUIHelper::getLocalIPs() -{ - static QStringList ips; - if (ips.count() == 0) { -#ifdef Q_OS_WASM - ips << "127.0.0.1"; -#else - QList netInterfaces = QNetworkInterface::allInterfaces(); - foreach (const QNetworkInterface &netInterface, netInterfaces) { - //移除虚拟机和抓包工具的虚拟网卡 - QString humanReadableName = netInterface.humanReadableName().toLower(); - if (humanReadableName.startsWith("vmware network adapter") || humanReadableName.startsWith("npcap loopback adapter")) { - continue; - } - - //过滤当前网络接口 - bool flag = (netInterface.flags() == (QNetworkInterface::IsUp | QNetworkInterface::IsRunning | QNetworkInterface::CanBroadcast | QNetworkInterface::CanMulticast)); - if (!flag) { - continue; - } - - QList addrs = netInterface.addressEntries(); - foreach (QNetworkAddressEntry addr, addrs) { - //只取出IPV4的地址 - if (addr.ip().protocol() != QAbstractSocket::IPv4Protocol) { - continue; - } - - QString ip4 = addr.ip().toString(); - if (ip4 != "127.0.0.1") { - ips << ip4; - } - } - } -#endif - } - - return ips; -} - -QList QUIHelper::colors = QList(); -QList QUIHelper::getColorList() -{ - //备用颜色集合 可以自行添加 - if (colors.count() == 0) { - colors << QColor(0, 176, 180) << QColor(0, 113, 193) << QColor(255, 192, 0); - colors << QColor(72, 103, 149) << QColor(185, 87, 86) << QColor(0, 177, 125); - colors << QColor(214, 77, 84) << QColor(71, 164, 233) << QColor(34, 163, 169); - colors << QColor(59, 123, 156) << QColor(162, 121, 197) << QColor(72, 202, 245); - colors << QColor(0, 150, 121) << QColor(111, 9, 176) << QColor(250, 170, 20); - } - - return colors; -} - -QStringList QUIHelper::getColorNames() -{ - QList colors = getColorList(); - QStringList colorNames; - foreach (QColor color, colors) { - colorNames << color.name(); - } - return colorNames; -} - -QColor QUIHelper::getRandColor() -{ - QList colors = getColorList(); - int index = getRandValue(0, colors.count(), true); - return colors.at(index); -} - -void QUIHelper::initRand() -{ - //初始化随机数种子 - QTime t = QTime::currentTime(); - srand(t.msec() + t.second() * 1000); -} - -float QUIHelper::getRandFloat(float min, float max) -{ - double diff = fabs(max - min); - double value = (double)(rand() % 100) / 100; - value = min + value * diff; - return value; -} - -double QUIHelper::getRandValue(int min, int max, bool contansMin, bool contansMax) -{ - int value; -#if (QT_VERSION <= QT_VERSION_CHECK(5,10,0)) - //通用公式 a是起始值,n是整数的范围 - //int value = a + rand() % n; - if (contansMin) { - if (contansMax) { - value = min + 0 + (rand() % (max - min + 1)); - } else { - value = min + 0 + (rand() % (max - min + 0)); - } - } else { - if (contansMax) { - value = min + 1 + (rand() % (max - min + 0)); - } else { - value = min + 1 + (rand() % (max - min - 1)); - } - } -#else - if (contansMin) { - if (contansMax) { - value = QRandomGenerator::global()->bounded(min + 0, max + 1); - } else { - value = QRandomGenerator::global()->bounded(min + 0, max + 0); - } - } else { - if (contansMax) { - value = QRandomGenerator::global()->bounded(min + 1, max + 1); - } else { - value = QRandomGenerator::global()->bounded(min + 1, max + 0); - } - } -#endif - return value; -} - -QStringList QUIHelper::getRandPoint(int count, float mainLng, float mainLat, float dotLng, float dotLat) -{ - //随机生成点坐标 - QStringList points; - for (int i = 0; i < count; ++i) { - //0.00881415 0.000442928 -#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0)) - float lngx = QRandomGenerator::global()->bounded(dotLng); - float latx = QRandomGenerator::global()->bounded(dotLat); -#else - float lngx = getRandFloat(dotLng / 10, dotLng); - float latx = getRandFloat(dotLat / 10, dotLat); -#endif - //需要先用精度转换成字符串 - QString lng2 = QString::number(mainLng + lngx, 'f', 8); - QString lat2 = QString::number(mainLat + latx, 'f', 8); - QString point = QString("%1,%2").arg(lng2).arg(lat2); - points << point; - } - - return points; -} - -QString QUIHelper::getUuid() -{ - QString uuid = QUuid::createUuid().toString(); - uuid.replace("{", ""); - uuid.replace("}", ""); - return uuid; -} - -void QUIHelper::newDir(const QString &dirName) -{ - QString strDir = dirName; - - //如果路径中包含斜杠字符则说明是绝对路径 - //linux系统路径字符带有 / windows系统 路径字符带有 :/ - if (!strDir.startsWith("/") && !strDir.contains(":/")) { - strDir = QString("%1/%2").arg(QUIHelper::appPath()).arg(strDir); - } - - QDir dir(strDir); - if (!dir.exists()) { - dir.mkpath(strDir); - } -} - -void QUIHelper::sleep(int msec) -{ - if (msec <= 0) { - return; - } - -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - QThread::msleep(msec); -#else - QTime endTime = QTime::currentTime().addMSecs(msec); - while (QTime::currentTime() < endTime) { - QCoreApplication::processEvents(QEventLoop::AllEvents, 100); - } -#endif -} - -void QUIHelper::setStyle() -{ - //打印下所有内置风格的名字 - qDebug() << TIMEMS << "QStyleFactory::keys" << QStyleFactory::keys(); - //设置内置风格 -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - qApp->setStyle(QStyleFactory::create("Fusion")); -#else - qApp->setStyle(QStyleFactory::create("Cleanlooks")); -#endif - - //设置指定颜色 - QPalette palette; - palette.setBrush(QPalette::Window, QColor("#F0F0F0")); - qApp->setPalette(palette); -} - -QFont QUIHelper::addFont(const QString &fontFile, const QString &fontName) -{ - //判断图形字体是否存在,不存在则加入 - QFontDatabase fontDb; - if (!fontDb.families().contains(fontName)) { - int fontId = fontDb.addApplicationFont(fontFile); - QStringList listName = fontDb.applicationFontFamilies(fontId); - if (listName.count() == 0) { - qDebug() << QString("load %1 error").arg(fontName); - } - } - - //再次判断是否包含字体名称防止加载失败 - QFont font; - if (fontDb.families().contains(fontName)) { - font = QFont(fontName); -#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0)) - font.setHintingPreference(QFont::PreferNoHinting); -#endif - } - - return font; -} - -void QUIHelper::setFont(int fontSize) -{ -#ifdef rk3399 - return; -#endif - //安卓套件在有些手机上默认字体不好看需要主动设置字体 - //网页套件需要主动加载中文字体才能正常显示中文 -#if (defined Q_OS_ANDROID) || (defined Q_OS_WASM) - QString fontFile = ":/font/DroidSansFallback.ttf"; - QString fontName = "Droid Sans Fallback"; - qApp->setFont(addFont(fontFile, fontName)); - return; -#endif - -#ifdef __arm__ - fontSize = 25; -#endif -#ifdef Q_OS_ANDROID - fontSize = 15; -#endif - - QFont font; - font.setFamily("MicroSoft Yahei"); - font.setPixelSize(fontSize); - qApp->setFont(font); -} - -void QUIHelper::setCode(bool utf8) -{ -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - //如果想要控制台打印信息中文正常就注释掉这个设置 - if (utf8) { - QTextCodec *codec = QTextCodec::codecForName("utf-8"); - QTextCodec::setCodecForLocale(codec); - } -#else -#if _MSC_VER - QTextCodec *codec = QTextCodec::codecForName("gbk"); -#else - QTextCodec *codec = QTextCodec::codecForName("utf-8"); -#endif - QTextCodec::setCodecForLocale(codec); - QTextCodec::setCodecForCStrings(codec); - QTextCodec::setCodecForTr(codec); -#endif -} - -void QUIHelper::setTranslator(const QString &qmFile) -{ - //过滤下不存在的就不用设置了 - if (!QFile(qmFile).exists()) { - return; - } - - QTranslator *translator = new QTranslator(qApp); - if (translator->load(qmFile)) { - qApp->installTranslator(translator); - } -} - -void QUIHelper::initAll(bool utf8, bool style, int fontSize) -{ - //初始化随机数种子 - QUIHelper::initRand(); - //设置编码 - QUIHelper::setCode(utf8); - //设置样式风格 - if (style) { - QUIHelper::setStyle(); - } - //设置字体 - QUIHelper::setFont(fontSize); - //设置翻译文件支持多个 - QUIHelper::setTranslator(":/qm/widgets.qm"); - QUIHelper::setTranslator(":/qm/qt_zh_CN.qm"); - QUIHelper::setTranslator(":/qm/designer_zh_CN.qm"); - //设置不使用本地系统环境代理配置 - QNetworkProxyFactory::setUseSystemConfiguration(false); -} - -void QUIHelper::initMain(bool on) -{ - //设置是否应用操作系统设置比如字体 - QApplication::setDesktopSettingsAware(on); - -#ifdef Q_OS_ANDROID -#if (QT_VERSION >= QT_VERSION_CHECK(5,6,0)) - //开启高分屏缩放支持 - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif -#else -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - //不应用任何缩放 - QApplication::setAttribute(Qt::AA_Use96Dpi); -#endif -#endif - -#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) - //高分屏缩放策略 - QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor); -#endif - -#if (QT_VERSION >= QT_VERSION_CHECK(5,4,0)) - //设置opengl模式 AA_UseDesktopOpenGL(默认) AA_UseOpenGLES AA_UseSoftwareOpenGL - //在一些很旧的设备上或者对opengl支持很低的设备上需要使用AA_UseOpenGLES表示禁用硬件加速 - //如果开启的是AA_UseOpenGLES则无法使用硬件加速比如ffmpeg的dxva2 - //QApplication::setAttribute(Qt::AA_UseOpenGLES); - //设置opengl共享上下文 - QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); -#endif -} - -QVector QUIHelper::msgTypes = QVector() << 0 << 1 << 2 << 3 << 4; -QVector QUIHelper::msgKeys = QVector() << "发送" << "接收" << "解析" << "错误" << "提示"; -QVector QUIHelper::msgColors = QVector() << QColor("#3BA372") << QColor("#EE6668") << QColor("#9861B4") << QColor("#FA8359") << QColor("#22A3A9"); -QString QUIHelper::appendMsg(QTextEdit *textEdit, int type, const QString &data, int maxCount, int ¤tCount, bool clear, bool pause) -{ - if (clear) { - textEdit->clear(); - currentCount = 0; - return QString(); - } - - if (pause) { - return QString(); - } - - if (currentCount >= maxCount) { - textEdit->clear(); - currentCount = 0; - } - - //不同类型不同颜色显示 - QString strType; - int index = msgTypes.indexOf(type); - if (index >= 0) { - strType = msgKeys.at(index); - textEdit->setTextColor(msgColors.at(index)); - } - - //过滤回车换行符 - QString strData = data; - strData.replace("\r", ""); - strData.replace("\n", ""); - strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData); - textEdit->append(strData); - currentCount++; - return strData; -} - -void QUIHelper::setFramelessForm(QWidget *widgetMain, bool tool, bool top, bool menu) -{ - widgetMain->setProperty("form", true); - widgetMain->setProperty("canMove", true); - - //根据设定逐个追加属性 -#ifdef __arm__ - widgetMain->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); -#else - widgetMain->setWindowFlags(Qt::FramelessWindowHint); -#endif - if (tool) { - widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::Tool); - } - if (top) { - widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowStaysOnTopHint); - } - if (menu) { - //如果是其他系统比如neokylin会产生系统边框 -#ifdef Q_OS_WIN - widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint); -#endif - } -} - -int QUIHelper::showMessageBox(const QString &info, int type, int closeSec, bool exec) -{ - int result = 0; - if (type == 0) { - showMessageBoxInfo(info, closeSec, exec); - } else if (type == 1) { - showMessageBoxError(info, closeSec, exec); - } else if (type == 2) { - result = showMessageBoxQuestion(info); - } - - return result; -} - -void QUIHelper::showMessageBoxInfo(const QString &info, int closeSec, bool exec) -{ - QMessageBox box(QMessageBox::Information, "提示", info); - box.setStandardButtons(QMessageBox::Yes); - box.setButtonText(QMessageBox::Yes, QString("确 定")); - box.exec(); - //QMessageBox::information(0, "提示", info, QMessageBox::Yes); -} - -void QUIHelper::showMessageBoxError(const QString &info, int closeSec, bool exec) -{ - QMessageBox box(QMessageBox::Critical, "错误", info); - box.setStandardButtons(QMessageBox::Yes); - box.setButtonText(QMessageBox::Yes, QString("确 定")); - box.exec(); - //QMessageBox::critical(0, "错误", info, QMessageBox::Yes); -} - -int QUIHelper::showMessageBoxQuestion(const QString &info) -{ - QMessageBox box(QMessageBox::Question, "询问", info); - box.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - box.setButtonText(QMessageBox::Yes, QString("确 定")); - box.setButtonText(QMessageBox::No, QString("取 消")); - return box.exec(); - //return QMessageBox::question(0, "询问", info, QMessageBox::Yes | QMessageBox::No); -} - -void QUIHelper::initDialog(QFileDialog *dialog, const QString &title, const QString &acceptName, - const QString &dirName, bool native, int width, int height) -{ - //设置标题 - dialog->setWindowTitle(title); - //设置标签文本 - dialog->setLabelText(QFileDialog::Accept, acceptName); - dialog->setLabelText(QFileDialog::Reject, "取消(&C)"); - dialog->setLabelText(QFileDialog::LookIn, "查看"); - dialog->setLabelText(QFileDialog::FileName, "名称"); - dialog->setLabelText(QFileDialog::FileType, "类型"); - - //设置默认显示目录 - if (!dirName.isEmpty()) { - dialog->setDirectory(dirName); - } - - //设置对话框宽高 - if (width > 0 && height > 0) { -#ifdef Q_OS_ANDROID - bool horizontal = (QUIHelper::deskWidth() > QUIHelper::deskHeight()); - if (horizontal) { - width = QUIHelper::deskWidth() / 2; - height = QUIHelper::deskHeight() - 50; - } else { - width = QUIHelper::deskWidth() - 10; - height = QUIHelper::deskHeight() / 2; - } -#endif - dialog->setFixedSize(width, height); - } - - //设置是否采用本地对话框 - dialog->setOption(QFileDialog::DontUseNativeDialog, !native); - //设置只读可以取消右上角的新建按钮 - //dialog->setReadOnly(true); -} - -QString QUIHelper::getDialogResult(QFileDialog *dialog) -{ - QString result; - if (dialog->exec() == QFileDialog::Accepted) { - result = dialog->selectedFiles().first(); - } - return result; -} - -QString QUIHelper::getOpenFileName(const QString &filter, const QString &dirName, const QString &fileName, - bool native, int width, int height) -{ - QFileDialog dialog; - initDialog(&dialog, "打开文件", "选择(&S)", dirName, native, width, height); - - //设置文件类型 - if (!filter.isEmpty()) { - dialog.setNameFilter(filter); - } - - //设置默认文件名称 - dialog.selectFile(fileName); - return getDialogResult(&dialog); -} - -QString QUIHelper::getSaveFileName(const QString &filter, const QString &dirName, const QString &fileName, - bool native, int width, int height) -{ - QFileDialog dialog; - initDialog(&dialog, "保存文件", "保存(&S)", dirName, native, width, height); - - //设置文件类型 - if (!filter.isEmpty()) { - dialog.setNameFilter(filter); - } - - //设置默认文件名称 - dialog.selectFile(fileName); - //设置模态类型允许输入 - dialog.setWindowModality(Qt::WindowModal); - //设置置顶显示 - dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint); - return getDialogResult(&dialog); -} - -QString QUIHelper::getExistingDirectory(const QString &dirName, bool native, int width, int height) -{ - QFileDialog dialog; - initDialog(&dialog, "选择目录", "选择(&S)", dirName, native, width, height); - dialog.setOption(QFileDialog::ReadOnly); - //设置只显示目录 -#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) - dialog.setFileMode(QFileDialog::DirectoryOnly); -#endif - dialog.setOption(QFileDialog::ShowDirsOnly); - return getDialogResult(&dialog); -} - -QString QUIHelper::getXorEncryptDecrypt(const QString &value, char key) -{ - //矫正范围外的数据 - if (key < 0 || key >= 127) { - key = 127; - } - - //大概从5.9版本输出的加密密码字符串前面会加上 @String 字符 - QString result = value; - if (result.startsWith("@String")) { - result = result.mid(8, result.length() - 9); - } - - int count = result.count(); - for (int i = 0; i < count; ++i) { - result[i] = QChar(result.at(i).toLatin1() ^ key); - } - return result; -} - -uchar QUIHelper::getOrCode(const QByteArray &data) -{ - int len = data.length(); - uchar result = 0; - for (int i = 0; i < len; ++i) { - result ^= data.at(i); - } - - return result; -} - -uchar QUIHelper::getCheckCode(const QByteArray &data) -{ - int len = data.length(); - uchar temp = 0; - for (uchar i = 0; i < len; ++i) { - temp += data.at(i); - } - - return temp % 256; -} - -void QUIHelper::initTableView(QTableView *tableView, int rowHeight, bool headVisible, bool edit, bool stretchLast) -{ - //设置弱属性用于应用qss特殊样式 - tableView->setProperty("model", true); - //取消自动换行 - tableView->setWordWrap(false); - //超出文本不显示省略号 - tableView->setTextElideMode(Qt::ElideNone); - //奇数偶数行颜色交替 - tableView->setAlternatingRowColors(false); - //垂直表头是否可见 - tableView->verticalHeader()->setVisible(headVisible); - //选中一行表头是否加粗 - tableView->horizontalHeader()->setHighlightSections(false); - //最后一行拉伸填充 - tableView->horizontalHeader()->setStretchLastSection(stretchLast); - //行标题最小宽度尺寸 - tableView->horizontalHeader()->setMinimumSectionSize(0); - //行标题最小高度,等同于和默认行高一致 - tableView->horizontalHeader()->setFixedHeight(rowHeight); - //默认行高 - tableView->verticalHeader()->setDefaultSectionSize(rowHeight); - //选中时一行整体选中 - tableView->setSelectionBehavior(QAbstractItemView::SelectRows); - //只允许选择单个 - tableView->setSelectionMode(QAbstractItemView::SingleSelection); - - //表头不可单击 -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - tableView->horizontalHeader()->setSectionsClickable(false); -#else - tableView->horizontalHeader()->setClickable(false); -#endif - - //鼠标按下即进入编辑模式 - if (edit) { - tableView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::DoubleClicked); - } else { - tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); - } -} - -void QUIHelper::openFile(const QString &fileName, const QString &msg) -{ -#ifdef __arm__ - return; -#endif - //文件不存在则不用处理 - if (!QFile(fileName).exists()) { - return; - } - if (QUIHelper::showMessageBoxQuestion(msg + "成功, 确定现在就打开吗?") == QMessageBox::Yes) { - QString url = QString("file:///%1").arg(fileName); - QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode)); - } -} - -bool QUIHelper::checkIniFile(const QString &iniFile) -{ - //如果配置文件大小为0,则以初始值继续运行,并生成配置文件 - QFile file(iniFile); - if (file.size() == 0) { - return false; - } - - //如果配置文件不完整,则以初始值继续运行,并生成配置文件 - if (file.open(QFile::ReadOnly)) { - bool ok = true; - while (!file.atEnd()) { - QString line = file.readLine(); - line.replace("\r", ""); - line.replace("\n", ""); - QStringList list = line.split("="); - - if (list.count() == 2) { - QString key = list.at(0); - QString value = list.at(1); - if (value.isEmpty()) { - qDebug() << TIMEMS << "ini node no value" << key; - ok = false; - break; - } - } - } - - if (!ok) { - return false; - } - } else { - return false; - } - - return true; -} - -QString QUIHelper::cutString(const QString &text, int len, int left, int right, const QString &mid) -{ - //如果是文件名则取文件名的前字符+末尾字符+去掉拓展名 - QString result = text.split(".").first(); - if (result.length() > len) { - result = QString("%1%2%3").arg(result.left(left)).arg(mid).arg(result.right(right)); - } - return result; -} diff --git a/tool/netserver/api/tcpserver1.cpp b/tool/netserver/api/tcpserver1.cpp index bd58893..67897b6 100644 --- a/tool/netserver/api/tcpserver1.cpp +++ b/tool/netserver/api/tcpserver1.cpp @@ -1,6 +1,6 @@ #include "tcpserver1.h" -#include "quihelper.h" -#include "quihelperdata.h" +#include "qthelper.h" +#include "qthelperdata.h" TcpClient1::TcpClient1(QObject *parent) : QTcpSocket(parent) { @@ -60,7 +60,7 @@ void TcpClient1::readData() QString buffer; if (AppConfig::HexData1) { - buffer = QUIHelperData::byteArrayToHexStr(data); + buffer = QtHelperData::byteArrayToHexStr(data); } else { buffer = QString(data); } @@ -72,7 +72,7 @@ void TcpClient1::sendData(const QString &data) { QByteArray buffer; if (AppConfig::HexData1) { - buffer = QUIHelperData::hexStrToByteArray(data); + buffer = QtHelperData::hexStrToByteArray(data); } else { buffer = data.toLatin1(); } diff --git a/tool/netserver/api/tcpserver2.cpp b/tool/netserver/api/tcpserver2.cpp index 4b82bc8..89026d7 100644 --- a/tool/netserver/api/tcpserver2.cpp +++ b/tool/netserver/api/tcpserver2.cpp @@ -1,6 +1,6 @@ #include "tcpserver2.h" -#include "quihelper.h" -#include "quihelperdata.h" +#include "qthelper.h" +#include "qthelperdata.h" TcpClient2::TcpClient2(QObject *parent) : QTcpSocket(parent) { @@ -60,7 +60,7 @@ void TcpClient2::readData() QString buffer; if (AppConfig::HexData2) { - buffer = QUIHelperData::byteArrayToHexStr(data); + buffer = QtHelperData::byteArrayToHexStr(data); } else { buffer = QString(data); } @@ -72,7 +72,7 @@ void TcpClient2::sendData(const QString &data) { QByteArray buffer; if (AppConfig::HexData2) { - buffer = QUIHelperData::hexStrToByteArray(data); + buffer = QtHelperData::hexStrToByteArray(data); } else { buffer = data.toLatin1(); } diff --git a/tool/netserver/form/frmmain.cpp b/tool/netserver/form/frmmain.cpp index 1518348..842bdd8 100644 --- a/tool/netserver/form/frmmain.cpp +++ b/tool/netserver/form/frmmain.cpp @@ -1,6 +1,6 @@ #include "frmmain.h" #include "ui_frmmain.h" -#include "quihelper.h" +#include "qthelper.h" frmMain::frmMain(QWidget *parent) : QWidget(parent), ui(new Ui::frmMain) { diff --git a/tool/netserver/main.cpp b/tool/netserver/main.cpp index 18b2ebb..8b36062 100644 --- a/tool/netserver/main.cpp +++ b/tool/netserver/main.cpp @@ -1,5 +1,5 @@ #include "frmmain.h" -#include "quihelper.h" +#include "qthelper.h" int main(int argc, char *argv[]) { @@ -14,16 +14,16 @@ int main(int argc, char *argv[]) a.setWindowIcon(QIcon(":/main.ico")); //设置编码以及加载中文翻译文件 - QUIHelper::initAll(); + QtHelper::initAll(); //读取配置文件 - AppConfig::ConfigFile = QString("%1/%2.ini").arg(QUIHelper::appPath()).arg(QUIHelper::appName()); + AppConfig::ConfigFile = QString("%1/%2.ini").arg(QtHelper::appPath()).arg(QtHelper::appName()); AppConfig::readConfig(); frmMain w; - w.setWindowTitle("网络中转服务器 V2022 (QQ: 517216493 WX: feiyangqingyun)"); + w.setWindowTitle("网络中转服务器 V2023 (QQ: 517216493 WX: feiyangqingyun)"); w.resize(900, 650); - QUIHelper::setFormInCenter(&w); + QtHelper::setFormInCenter(&w); w.show(); return a.exec(); diff --git a/tool/nettool/api/api.pri b/tool/nettool/api/api.pri index e83bc79..13454c7 100644 --- a/tool/nettool/api/api.pri +++ b/tool/nettool/api/api.pri @@ -1,17 +1,3 @@ -HEADERS += $$PWD/appconfig.h \ - $$PWD/appdata.h \ - $$PWD/quihelper.h \ - $$PWD/quihelperdata.h -HEADERS += $$PWD/tcpclient.h -HEADERS += $$PWD/tcpserver.h - -SOURCES += $$PWD/appconfig.cpp \ - $$PWD/appdata.cpp \ - $$PWD/quihelper.cpp \ - $$PWD/quihelperdata.cpp -SOURCES += $$PWD/tcpclient.cpp -SOURCES += $$PWD/tcpserver.cpp - contains(DEFINES, websocket) { HEADERS += $$PWD/webclient.h HEADERS += $$PWD/webserver.h @@ -19,3 +5,19 @@ HEADERS += $$PWD/webserver.h SOURCES += $$PWD/webclient.cpp SOURCES += $$PWD/webserver.cpp } + +HEADERS += \ + $$PWD/appconfig.h \ + $$PWD/appdata.h \ + $$PWD/qthelper.h \ + $$PWD/qthelperdata.h \ + $$PWD/tcpclient.h \ + $$PWD/tcpserver.h + +SOURCES += \ + $$PWD/appconfig.cpp \ + $$PWD/appdata.cpp \ + $$PWD/qthelper.cpp \ + $$PWD/qthelperdata.cpp \ + $$PWD/tcpclient.cpp \ + $$PWD/tcpserver.cpp diff --git a/tool/nettool/api/appconfig.cpp b/tool/nettool/api/appconfig.cpp index ed708c9..c0b8151 100644 --- a/tool/nettool/api/appconfig.cpp +++ b/tool/nettool/api/appconfig.cpp @@ -1,5 +1,5 @@ #include "appconfig.h" -#include "quihelper.h" +#include "qthelper.h" QString AppConfig::ConfigFile = "config.ini"; int AppConfig::CurrentIndex = 0; @@ -147,7 +147,7 @@ void AppConfig::readConfig() set.endGroup(); //配置文件不存在或者不全则重新生成 - if (!QUIHelper::checkIniFile(AppConfig::ConfigFile)) { + if (!QtHelper::checkIniFile(AppConfig::ConfigFile)) { writeConfig(); return; } diff --git a/tool/nettool/api/appdata.cpp b/tool/nettool/api/appdata.cpp index 7ad8454..5376711 100644 --- a/tool/nettool/api/appdata.cpp +++ b/tool/nettool/api/appdata.cpp @@ -1,5 +1,5 @@ #include "appdata.h" -#include "quihelper.h" +#include "qthelper.h" QStringList AppData::Intervals = QStringList(); QStringList AppData::Datas = QStringList(); @@ -11,7 +11,7 @@ void AppData::readSendData() { //读取发送数据列表 AppData::Datas.clear(); - QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(AppData::SendFileName); + QString fileName = QString("%1/%2").arg(QtHelper::appPath()).arg(AppData::SendFileName); QFile file(fileName); if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) { while (!file.atEnd()) { @@ -39,7 +39,7 @@ void AppData::readDeviceData() //读取转发数据列表 AppData::Keys.clear(); AppData::Values.clear(); - QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(AppData::DeviceFileName); + QString fileName = QString("%1/%2").arg(QtHelper::appPath()).arg(AppData::DeviceFileName); QFile file(fileName); if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) { while (!file.atEnd()) { @@ -72,7 +72,7 @@ void AppData::saveData(const QString &data) return; } - QString fileName = QString("%1/%2.txt").arg(QUIHelper::appPath()).arg(STRDATETIME); + QString fileName = QString("%1/%2.txt").arg(QtHelper::appPath()).arg(STRDATETIME); QFile file(fileName); if (file.open(QFile::WriteOnly | QFile::Text)) { file.write(data.toUtf8()); diff --git a/tool/nettool/api/qthelper.cpp b/tool/nettool/api/qthelper.cpp new file mode 100644 index 0000000..1911055 --- /dev/null +++ b/tool/nettool/api/qthelper.cpp @@ -0,0 +1,1234 @@ +#include "qthelper.h" +#include "qnetworkinterface.h" +#include "qnetworkproxy.h" + +#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz")) + +QList QtHelper::getScreenRects(bool available) +{ + QList rects; +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + int screenCount = qApp->screens().count(); + QList screens = qApp->screens(); + for (int i = 0; i < screenCount; ++i) { + QScreen *screen = screens.at(i); + rects << (available ? screen->availableGeometry() : screen->geometry()); + } +#else + int screenCount = qApp->desktop()->screenCount(); + QDesktopWidget *desk = qApp->desktop(); + for (int i = 0; i < screenCount; ++i) { + rects << (available ? desk->availableGeometry(i) : desk->screenGeometry(i)); + } +#endif + return rects; +} + +int QtHelper::getScreenIndex() +{ + //需要对多个屏幕进行处理 + int screenIndex = 0; + QList rects = getScreenRects(false); + int count = rects.count(); + for (int i = 0; i < count; ++i) { + //找到当前鼠标所在屏幕 + QPoint pos = QCursor::pos(); + if (rects.at(i).contains(pos)) { + screenIndex = i; + break; + } + } + + return screenIndex; +} + +QRect QtHelper::getScreenRect(bool available) +{ + int screenIndex = getScreenIndex(); + QList rects = getScreenRects(available); + return rects.at(screenIndex); +} + +qreal QtHelper::getScreenRatio(bool devicePixel) +{ + qreal ratio = 1.0; + int screenIndex = getScreenIndex(); +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + QScreen *screen = qApp->screens().at(screenIndex); + if (devicePixel) { + //需要开启 AA_EnableHighDpiScaling 属性才能正常获取 + ratio = screen->devicePixelRatio() * 100; + } else { + ratio = screen->logicalDotsPerInch(); + } +#else + //Qt4不能动态识别缩放更改后的值 + ratio = qApp->desktop()->screen(screenIndex)->logicalDpiX(); +#endif + return ratio / 96; +} + +QRect QtHelper::checkCenterRect(QRect &rect, bool available) +{ + QRect deskRect = QtHelper::getScreenRect(available); + int formWidth = rect.width(); + int formHeight = rect.height(); + int deskWidth = deskRect.width(); + int deskHeight = deskRect.height(); + int formX = deskWidth / 2 - formWidth / 2 + deskRect.x(); + int formY = deskHeight / 2 - formHeight / 2; + rect = QRect(formX, formY, formWidth, formHeight); + return deskRect; +} + +int QtHelper::deskWidth() +{ + return getScreenRect().width(); +} + +int QtHelper::deskHeight() +{ + return getScreenRect().height(); +} + +QSize QtHelper::deskSize() +{ + return getScreenRect().size(); +} + +QWidget *QtHelper::centerBaseForm = 0; +void QtHelper::setFormInCenter(QWidget *form) +{ + int formWidth = form->width(); + int formHeight = form->height(); + + //如果=0表示采用系统桌面屏幕为参照 + QRect rect; + if (centerBaseForm == 0) { + rect = getScreenRect(); + } else { + rect = centerBaseForm->geometry(); + } + + int deskWidth = rect.width(); + int deskHeight = rect.height(); + QPoint movePoint(deskWidth / 2 - formWidth / 2 + rect.x(), deskHeight / 2 - formHeight / 2 + rect.y()); + form->move(movePoint); +} + +void QtHelper::showForm(QWidget *form) +{ + setFormInCenter(form); + form->show(); + + //判断宽高是否超过了屏幕分辨率,超过了则最大化显示 + //qDebug() << TIMEMS << form->size() << deskSize(); + if (form->width() + 20 > deskWidth() || form->height() + 50 > deskHeight()) { + QMetaObject::invokeMethod(form, "showMaximized", Qt::QueuedConnection); + } +} + +QString QtHelper::appName() +{ + //没有必要每次都获取,只有当变量为空时才去获取一次 + static QString name; + if (name.isEmpty()) { + name = qApp->applicationFilePath(); + //下面的方法主要为了过滤安卓的路径 lib程序名_armeabi-v7a/lib程序名_arm64-v8a + QStringList list = name.split("/"); + name = list.at(list.count() - 1).split(".").at(0); + name.replace("_armeabi-v7a", ""); + name.replace("_arm64-v8a", ""); + } + + return name; +} + +QString QtHelper::appPath() +{ + static QString path; + if (path.isEmpty()) { +#ifdef Q_OS_ANDROID + //默认安卓根目录 + path = "/storage/emulated/0"; + //带上程序名称作为目录 前面加个0方便排序 + path = path + "/0" + appName(); +#else + path = qApp->applicationDirPath(); +#endif + } + + return path; +} + +void QtHelper::getCurrentInfo(char *argv[], QString &path, QString &name) +{ + //必须用fromLocal8Bit保证中文路径正常 + QString argv0 = QString::fromLocal8Bit(argv[0]); + QFileInfo file(argv0); + path = file.path(); + name = file.baseName(); +} + +QString QtHelper::getIniValue(const QString &fileName, const QString &key) +{ + QString value; + QFile file(fileName); + if (file.open(QFile::ReadOnly | QFile::Text)) { + while (!file.atEnd()) { + QString line = file.readLine(); + if (line.startsWith(key)) { + line = line.replace("\n", ""); + line = line.trimmed(); + value = line.split("=").last(); + break; + } + } + } + return value; +} + +QString QtHelper::getIniValue(char *argv[], const QString &key, const QString &dir) +{ + QString path, name; + QtHelper::getCurrentInfo(argv, path, name); + QString fileName = QString("%1/%2%3.ini").arg(path).arg(dir).arg(name); + return getIniValue(fileName, key); +} + +QStringList QtHelper::getLocalIPs() +{ + static QStringList ips; + if (ips.count() == 0) { +#ifdef Q_OS_WASM + ips << "127.0.0.1"; +#else + QList netInterfaces = QNetworkInterface::allInterfaces(); + foreach (QNetworkInterface netInterface, netInterfaces) { + //移除虚拟机和抓包工具的虚拟网卡 + QString humanReadableName = netInterface.humanReadableName().toLower(); + if (humanReadableName.startsWith("vmware network adapter") || humanReadableName.startsWith("npcap loopback adapter")) { + continue; + } + + //过滤当前网络接口 + bool flag = (netInterface.flags() == (QNetworkInterface::IsUp | QNetworkInterface::IsRunning | QNetworkInterface::CanBroadcast | QNetworkInterface::CanMulticast)); + if (!flag) { + continue; + } + + QList addrs = netInterface.addressEntries(); + foreach (QNetworkAddressEntry addr, addrs) { + //只取出IPV4的地址 + if (addr.ip().protocol() != QAbstractSocket::IPv4Protocol) { + continue; + } + + QString ip4 = addr.ip().toString(); + if (ip4 != "127.0.0.1") { + ips << ip4; + } + } + } +#endif + } + + return ips; +} + +QList QtHelper::colors = QList(); +QList QtHelper::getColorList() +{ + //备用颜色集合 可以自行添加 + if (colors.count() == 0) { + colors << QColor(0, 176, 180) << QColor(0, 113, 193) << QColor(255, 192, 0); + colors << QColor(72, 103, 149) << QColor(185, 87, 86) << QColor(0, 177, 125); + colors << QColor(214, 77, 84) << QColor(71, 164, 233) << QColor(34, 163, 169); + colors << QColor(59, 123, 156) << QColor(162, 121, 197) << QColor(72, 202, 245); + colors << QColor(0, 150, 121) << QColor(111, 9, 176) << QColor(250, 170, 20); + } + + return colors; +} + +QStringList QtHelper::getColorNames() +{ + QList colors = getColorList(); + QStringList colorNames; + foreach (QColor color, colors) { + colorNames << color.name(); + } + return colorNames; +} + +QColor QtHelper::getRandColor() +{ + QList colors = getColorList(); + int index = getRandValue(0, colors.count(), true); + return colors.at(index); +} + +void QtHelper::initRand() +{ + //初始化随机数种子 + QTime t = QTime::currentTime(); + srand(t.msec() + t.second() * 1000); +} + +float QtHelper::getRandFloat(float min, float max) +{ + double diff = fabs(max - min); + double value = (double)(rand() % 100) / 100; + value = min + value * diff; + return value; +} + +double QtHelper::getRandValue(int min, int max, bool contansMin, bool contansMax) +{ + int value; +#if (QT_VERSION <= QT_VERSION_CHECK(5,10,0)) + //通用公式 a是起始值,n是整数的范围 + //int value = a + rand() % n; + if (contansMin) { + if (contansMax) { + value = min + 0 + (rand() % (max - min + 1)); + } else { + value = min + 0 + (rand() % (max - min + 0)); + } + } else { + if (contansMax) { + value = min + 1 + (rand() % (max - min + 0)); + } else { + value = min + 1 + (rand() % (max - min - 1)); + } + } +#else + if (contansMin) { + if (contansMax) { + value = QRandomGenerator::global()->bounded(min + 0, max + 1); + } else { + value = QRandomGenerator::global()->bounded(min + 0, max + 0); + } + } else { + if (contansMax) { + value = QRandomGenerator::global()->bounded(min + 1, max + 1); + } else { + value = QRandomGenerator::global()->bounded(min + 1, max + 0); + } + } +#endif + return value; +} + +QStringList QtHelper::getRandPoint(int count, float mainLng, float mainLat, float dotLng, float dotLat) +{ + //随机生成点坐标 + QStringList points; + for (int i = 0; i < count; ++i) { + //0.00881415 0.000442928 +#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0)) + float lngx = QRandomGenerator::global()->bounded(dotLng); + float latx = QRandomGenerator::global()->bounded(dotLat); +#else + float lngx = getRandFloat(dotLng / 10, dotLng); + float latx = getRandFloat(dotLat / 10, dotLat); +#endif + //需要先用精度转换成字符串 + QString lng2 = QString::number(mainLng + lngx, 'f', 8); + QString lat2 = QString::number(mainLat + latx, 'f', 8); + QString point = QString("%1,%2").arg(lng2).arg(lat2); + points << point; + } + + return points; +} + +int QtHelper::getRangeValue(int oldMin, int oldMax, int oldValue, int newMin, int newMax) +{ + return (((oldValue - oldMin) * (newMax - newMin)) / (oldMax - oldMin)) + newMin; +} + +QString QtHelper::getUuid() +{ + QString uuid = QUuid::createUuid().toString(); + uuid.replace("{", ""); + uuid.replace("}", ""); + return uuid; +} + +void QtHelper::checkPath(const QString &dirName) +{ + //相对路径需要补全完整路径 + QString path = dirName; + if (path.startsWith("./")) { + path.replace(".", ""); + path = QtHelper::appPath() + path; + } else if (!path.startsWith("/") && !path.contains(":/")) { + path = QtHelper::appPath() + "/" + path; + } + + //目录不存在则新建 + QDir dir(path); + if (!dir.exists()) { + dir.mkpath(path); + } +} + +void QtHelper::sleep(int msec, bool exec) +{ + if (msec <= 0) { + return; + } + + if (exec) { +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //阻塞方式延时(如果在主线程会卡住主界面) + QThread::msleep(msec); +#else + //非阻塞方式延时(不会卡住主界面/据说可能有问题) + QTime endTime = QTime::currentTime().addMSecs(msec); + while (QTime::currentTime() < endTime) { + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + } +#endif + } else { + //非阻塞方式延时(现在很多人推荐的方法) + QEventLoop loop; + QTimer::singleShot(msec, &loop, SLOT(quit())); + loop.exec(); + } +} + +void QtHelper::checkRun() +{ +#ifdef Q_OS_WIN + //延时1秒钟,等待程序释放完毕 + QtHelper::sleep(1000); + //创建共享内存,判断是否已经运行程序 + static QSharedMemory mem(QtHelper::appName()); + if (!mem.create(1)) { + QtHelper::showMessageBoxError("程序已运行, 软件将自动关闭!", 5, true); + exit(0); + } +#endif +} + +void QtHelper::setStyle() +{ + //打印下所有内置风格的名字 + qDebug() << TIMEMS << "QStyleFactory::keys" << QStyleFactory::keys(); + //设置内置风格 +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + qApp->setStyle("Fusion"); +#else + qApp->setStyle("Cleanlooks"); +#endif + + //设置指定颜色 + QPalette palette; + palette.setBrush(QPalette::Window, QColor("#F0F0F0")); + qApp->setPalette(palette); +} + +QFont QtHelper::addFont(const QString &fontFile, const QString &fontName) +{ + //判断图形字体是否存在,不存在则加入 + QFontDatabase fontDb; + if (!fontDb.families().contains(fontName)) { + int fontId = fontDb.addApplicationFont(fontFile); + QStringList listName = fontDb.applicationFontFamilies(fontId); + if (listName.count() == 0) { + qDebug() << QString("load %1 error").arg(fontName); + } + } + + //再次判断是否包含字体名称防止加载失败 + QFont font; + if (fontDb.families().contains(fontName)) { + font = QFont(fontName); +#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0)) + font.setHintingPreference(QFont::PreferNoHinting); +#endif + } + + return font; +} + +void QtHelper::setFont(int fontSize) +{ + //安卓套件在有些手机上默认字体不好看需要主动设置字体 + //网页套件需要主动加载中文字体才能正常显示中文 +#if (defined Q_OS_ANDROID) || (defined Q_OS_WASM) + QString fontFile = ":/font/DroidSansFallback.ttf"; + QString fontName = "Droid Sans Fallback"; + qApp->setFont(addFont(fontFile, fontName)); + return; +#endif + +#ifdef __arm__ + fontSize = 25; +#endif + + QFont font; + font.setFamily("MicroSoft Yahei"); + font.setPixelSize(fontSize); + qApp->setFont(font); +} + +void QtHelper::setCode(bool utf8) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //如果想要控制台打印信息中文正常就注释掉这个设置 + if (utf8) { + QTextCodec *codec = QTextCodec::codecForName("utf-8"); + QTextCodec::setCodecForLocale(codec); + } +#else +#if _MSC_VER + QTextCodec *codec = QTextCodec::codecForName("gbk"); +#else + QTextCodec *codec = QTextCodec::codecForName("utf-8"); +#endif + QTextCodec::setCodecForLocale(codec); + QTextCodec::setCodecForCStrings(codec); + QTextCodec::setCodecForTr(codec); +#endif +} + +void QtHelper::setTranslator(const QString &qmFile) +{ + //过滤下不存在的就不用设置了 + if (!QFile(qmFile).exists()) { + return; + } + + QTranslator *translator = new QTranslator(qApp); + if (translator->load(qmFile)) { + qApp->installTranslator(translator); + } +} + +#ifdef Q_OS_ANDROID +#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) +#include +#else +//Qt6中将相关类移到了core模块而且名字变了 +#include +#endif +#endif + +bool QtHelper::checkPermission(const QString &permission) +{ +#ifdef Q_OS_ANDROID +#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0) && QT_VERSION < QT_VERSION_CHECK(6,0,0)) + QtAndroid::PermissionResult result = QtAndroid::checkPermission(permission); + if (result == QtAndroid::PermissionResult::Denied) { + QtAndroid::requestPermissionsSync(QStringList() << permission); + result = QtAndroid::checkPermission(permission); + if (result == QtAndroid::PermissionResult::Denied) { + return false; + } + } +#else + QFuture result = QtAndroidPrivate::requestPermission(permission); + if (result.resultAt(0) == QtAndroidPrivate::PermissionResult::Denied) { + return false; + } +#endif +#endif + return true; +} + +void QtHelper::initAndroidPermission() +{ + //可以把所有要动态申请的权限都写在这里 + checkPermission("android.permission.CALL_PHONE"); + checkPermission("android.permission.SEND_SMS"); + checkPermission("android.permission.CAMERA"); + checkPermission("android.permission.READ_EXTERNAL_STORAGE"); + checkPermission("android.permission.WRITE_EXTERNAL_STORAGE"); + + checkPermission("android.permission.ACCESS_COARSE_LOCATION"); + checkPermission("android.permission.BLUETOOTH"); + checkPermission("android.permission.BLUETOOTH_SCAN"); + checkPermission("android.permission.BLUETOOTH_CONNECT"); + checkPermission("android.permission.BLUETOOTH_ADVERTISE"); +} + +void QtHelper::initAll(bool utf8, bool style, int fontSize) +{ + //初始化安卓权限 + QtHelper::initAndroidPermission(); + //初始化随机数种子 + QtHelper::initRand(); + //设置编码 + QtHelper::setCode(utf8); + //设置字体 + QtHelper::setFont(fontSize); + //设置样式风格 + if (style) { + QtHelper::setStyle(); + } + + //设置翻译文件支持多个 + QtHelper::setTranslator(":/qm/widgets.qm"); + QtHelper::setTranslator(":/qm/qt_zh_CN.qm"); + QtHelper::setTranslator(":/qm/designer_zh_CN.qm"); + + //设置不使用本地系统环境代理配置 + QNetworkProxyFactory::setUseSystemConfiguration(false); + //设置当前目录为程序可执行文件所在目录 + QDir::setCurrent(QtHelper::appPath()); + //Qt4中默认没有程序名称需要主动设置 +#if (QT_VERSION < QT_VERSION_CHECK(5,0,0)) + qApp->setApplicationName(QtHelper::appName()); +#endif +} + +void QtHelper::initMain(bool desktopSettingsAware, bool use96Dpi, bool logCritical) +{ +#ifdef Q_OS_WIN + //Qt6.5开始默认是ffmpeg后端但是不成熟需要换成系统的 + qputenv("QT_MEDIA_BACKEND", "windows"); +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //设置是否应用操作系统设置比如字体 + QApplication::setDesktopSettingsAware(desktopSettingsAware); +#endif + + bool highDpi = !use96Dpi; +#ifdef Q_OS_ANDROID + highDpi = true; +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,6,0)) + //开启高分屏缩放支持 + if (highDpi) { + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + } +#endif + +#ifdef Q_OS_WIN + if (use96Dpi) { + //Qt6中AA_Use96Dpi没效果必须下面方式设置强制指定缩放DPI + qputenv("QT_FONT_DPI", "96"); +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //不应用任何缩放 + QApplication::setAttribute(Qt::AA_Use96Dpi); +#endif + } +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) + //高分屏缩放策略 + QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor); +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + //下面这行表示不打印Qt内部类的警告提示信息 + if (!logCritical) { + QLoggingCategory::setFilterRules("*.critical=false\n*.warning=false"); + } +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5,4,0)) + //设置opengl共享上下文 + QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); +#endif +} + +void QtHelper::initOpenGL(quint8 type, bool checkCardEnable, bool checkVirtualSystem) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5,4,0)) + //设置opengl模式 AA_UseDesktopOpenGL(默认) AA_UseOpenGLES AA_UseSoftwareOpenGL + //在一些很旧的设备上或者对opengl支持很低的设备上需要使用AA_UseOpenGLES表示禁用硬件加速 + //如果开启的是AA_UseOpenGLES则无法使用硬件加速比如ffmpeg的dxva2 + if (type == 1) { + QApplication::setAttribute(Qt::AA_UseDesktopOpenGL); + } else if (type == 2) { + QApplication::setAttribute(Qt::AA_UseOpenGLES); + } else if (type == 3) { + QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); + } + + //检测显卡是否被禁用 + if (checkCardEnable && !isVideoCardEnable()) { + QApplication::setAttribute(Qt::AA_UseOpenGLES); + } + + //检测是否是虚拟机系统 + if (checkVirtualSystem && isVirtualSystem()) { + QApplication::setAttribute(Qt::AA_UseOpenGLES); + } +#endif +} + +QString QtHelper::doCmd(const QString &program, const QStringList &arguments, int timeout) +{ + QString result; +#ifndef Q_OS_WASM + QProcess p; + p.start(program, arguments); + p.waitForFinished(timeout); + result = QString::fromLocal8Bit(p.readAllStandardOutput()); + result.replace("\r", ""); + result.replace("\n", ""); + result = result.simplified(); + result = result.trimmed(); +#endif + return result; +} + +bool QtHelper::isVideoCardEnable() +{ + QString result; + bool videoCardEnable = true; + +#if defined(Q_OS_WIN) + QStringList args; + //wmic path win32_VideoController get name,Status + args << "path" << "win32_VideoController" << "get" << "name,Status"; + result = doCmd("wmic", args); +#endif + + //Name Status Intel(R) UHD Graphics 630 OK + //Name Status Intel(R) UHD Graphics 630 Error + if (result.contains("Error")) { + videoCardEnable = false; + } + + return videoCardEnable; +} + +bool QtHelper::isVirtualSystem() +{ + QString result; + bool virtualSystem = false; + +#if defined(Q_OS_WIN) + QStringList args; + //wmic computersystem get Model + args << "computersystem" << "get" << "Model"; + result = doCmd("wmic", args); +#elif defined(Q_OS_LINUX) + QStringList args; + //还有个命令需要root权限运行 dmidecode -s system-product-name 执行结果和win一样 + result = doCmd("lscpu", args); +#endif + + //Model MS-7C00 + //Model VMWare Virtual Platform + //Model VirtualBox Virtual Platform + //Model Alibaba Cloud ECS + if (result.contains("VMware") || result.contains("VirtualBox") || result.contains("Alibaba")) { + virtualSystem = true; + } + + return virtualSystem; +} + +QVector QtHelper::msgTypes = QVector() << 0 << 1 << 2 << 3 << 4; +QVector QtHelper::msgKeys = QVector() << QString::fromUtf8("发送") << QString::fromUtf8("接收") << QString::fromUtf8("解析") << QString::fromUtf8("错误") << QString::fromUtf8("提示"); +QVector QtHelper::msgColors = QVector() << QColor("#3BA372") << QColor("#EE6668") << QColor("#9861B4") << QColor("#FA8359") << QColor("#22A3A9"); +QString QtHelper::appendMsg(QTextEdit *textEdit, int type, const QString &data, int maxCount, int ¤tCount, bool clear, bool pause) +{ + if (clear) { + textEdit->clear(); + currentCount = 0; + return QString(); + } + + if (pause) { + return QString(); + } + + if (currentCount >= maxCount) { + textEdit->clear(); + currentCount = 0; + } + + //不同类型不同颜色显示 + QString strType; + int index = msgTypes.indexOf(type); + if (index >= 0) { + strType = msgKeys.at(index); + textEdit->setTextColor(msgColors.at(index)); + } + + //过滤回车换行符 + QString strData = data; + strData.replace("\r", ""); + strData.replace("\n", ""); + strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData); + textEdit->append(strData); + currentCount++; + return strData; +} + +void QtHelper::setFramelessForm(QWidget *widgetMain, bool tool, bool top, bool menu) +{ + widgetMain->setProperty("form", true); + widgetMain->setProperty("canMove", true); + + //根据设定逐个追加属性 +#ifdef __arm__ + widgetMain->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); +#else + widgetMain->setWindowFlags(Qt::FramelessWindowHint); +#endif + if (tool) { + widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::Tool); + } + if (top) { + widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowStaysOnTopHint); + } + if (menu) { + //如果是其他系统比如neokylin会产生系统边框 +#ifdef Q_OS_WIN + widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint); +#endif + } +} + +int QtHelper::showMessageBox(const QString &text, int type, int closeSec, bool exec) +{ + int result = 0; + if (type == 0) { + showMessageBoxInfo(text, closeSec, exec); + } else if (type == 1) { + showMessageBoxError(text, closeSec, exec); + } else if (type == 2) { + result = showMessageBoxQuestion(text); + } + + return result; +} + +void QtHelper::showMessageBoxInfo(const QString &text, int closeSec, bool exec) +{ + QMessageBox box(QMessageBox::Information, "提示", text); + box.setStandardButtons(QMessageBox::Yes); + box.setButtonText(QMessageBox::Yes, QString("确 定")); + box.exec(); + //QMessageBox::information(0, "提示", info, QMessageBox::Yes); +} + +void QtHelper::showMessageBoxError(const QString &text, int closeSec, bool exec) +{ + QMessageBox box(QMessageBox::Critical, "错误", text); + box.setStandardButtons(QMessageBox::Yes); + box.setButtonText(QMessageBox::Yes, QString("确 定")); + box.exec(); + //QMessageBox::critical(0, "错误", info, QMessageBox::Yes); +} + +int QtHelper::showMessageBoxQuestion(const QString &text) +{ + QMessageBox box(QMessageBox::Question, "询问", text); + box.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + box.setButtonText(QMessageBox::Yes, QString("确 定")); + box.setButtonText(QMessageBox::No, QString("取 消")); + return box.exec(); + //return QMessageBox::question(0, "询问", info, QMessageBox::Yes | QMessageBox::No); +} + +void QtHelper::initDialog(QFileDialog *dialog, const QString &title, const QString &acceptName, + const QString &dirName, bool native, int width, int height) +{ + //设置标题 + dialog->setWindowTitle(title); + //设置标签文本 + dialog->setLabelText(QFileDialog::Accept, acceptName); + dialog->setLabelText(QFileDialog::Reject, "取消(&C)"); + dialog->setLabelText(QFileDialog::LookIn, "查看"); + dialog->setLabelText(QFileDialog::FileName, "名称"); + dialog->setLabelText(QFileDialog::FileType, "类型"); + + //设置默认显示目录 + if (!dirName.isEmpty()) { + dialog->setDirectory(dirName); + } + + //设置对话框宽高 + if (width > 0 && height > 0) { +#ifdef Q_OS_ANDROID + bool horizontal = (QtHelper::deskWidth() > QtHelper::deskHeight()); + if (horizontal) { + width = QtHelper::deskWidth() / 2; + height = QtHelper::deskHeight() - 50; + } else { + width = QtHelper::deskWidth() - 10; + height = QtHelper::deskHeight() / 2; + } +#endif + dialog->setFixedSize(width, height); + } + + //设置是否采用本地对话框 + dialog->setOption(QFileDialog::DontUseNativeDialog, !native); + //设置只读可以取消右上角的新建按钮 + //dialog->setReadOnly(true); +} + +QString QtHelper::getDialogResult(QFileDialog *dialog) +{ + QString result; + if (dialog->exec() == QFileDialog::Accepted) { + result = dialog->selectedFiles().first(); + if (!result.contains(".")) { + //自动补全拓展名 保存文件(*.txt *.exe) + QString filter = dialog->selectedNameFilter(); + if (filter.contains("*.")) { + filter = filter.split("(").last(); + filter = filter.mid(0, filter.length() - 1); + //取出第一个作为拓展名 + if (!filter.contains("*.*")) { + filter = filter.split(" ").first(); + result = result + filter.mid(1, filter.length()); + } + } + } + } + return result; +} + +QString QtHelper::getOpenFileName(const QString &filter, const QString &dirName, const QString &fileName, + bool native, int width, int height) +{ + QFileDialog dialog; + initDialog(&dialog, "打开文件", "选择(&S)", dirName, native, width, height); + + //设置文件类型 + if (!filter.isEmpty()) { + dialog.setNameFilter(filter); + } + + //设置默认文件名称 + dialog.selectFile(fileName); + return getDialogResult(&dialog); +} + +QString QtHelper::getSaveFileName(const QString &filter, const QString &dirName, const QString &fileName, + bool native, int width, int height) +{ + QFileDialog dialog; + initDialog(&dialog, "保存文件", "保存(&S)", dirName, native, width, height); + + //设置文件类型 + if (!filter.isEmpty()) { + dialog.setNameFilter(filter); + } + + //设置默认文件名称 + dialog.selectFile(fileName); + //设置模态类型允许输入 + dialog.setWindowModality(Qt::WindowModal); + //设置置顶显示 + dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint); + return getDialogResult(&dialog); +} + +QString QtHelper::getExistingDirectory(const QString &dirName, bool native, int width, int height) +{ + QFileDialog dialog; + initDialog(&dialog, "选择目录", "选择(&S)", dirName, native, width, height); + dialog.setOption(QFileDialog::ReadOnly); + //设置只显示目录 +#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) + dialog.setFileMode(QFileDialog::DirectoryOnly); +#endif + dialog.setOption(QFileDialog::ShowDirsOnly); + return getDialogResult(&dialog); +} + +QString QtHelper::getXorEncryptDecrypt(const QString &value, char key) +{ + //矫正范围外的数据 + if (key < 0 || key >= 127) { + key = 127; + } + + //大概从5.9版本输出的加密密码字符串前面会加上 @String 字符 + QString result = value; + if (result.startsWith("@String")) { + result = result.mid(8, result.length() - 9); + } + + for (int i = 0; i < result.length(); ++i) { + result[i] = QChar(result.at(i).toLatin1() ^ key); + } + return result; +} + +quint8 QtHelper::getOrCode(const QByteArray &data) +{ + int len = data.length(); + quint8 result = 0; + for (int i = 0; i < len; ++i) { + result ^= data.at(i); + } + + return result; +} + +quint8 QtHelper::getCheckCode(const QByteArray &data) +{ + int len = data.length(); + quint8 temp = 0; + for (int i = 0; i < len; ++i) { + temp += data.at(i); + } + + return temp % 256; +} + +void QtHelper::initTableView(QTableView *tableView, int rowHeight, bool headVisible, bool edit, bool stretchLast) +{ + //设置弱属性用于应用qss特殊样式 + tableView->setProperty("model", true); + //取消自动换行 + tableView->setWordWrap(false); + //超出文本不显示省略号 + tableView->setTextElideMode(Qt::ElideNone); + //奇数偶数行颜色交替 + tableView->setAlternatingRowColors(false); + //垂直表头是否可见 + tableView->verticalHeader()->setVisible(headVisible); + //选中一行表头是否加粗 + tableView->horizontalHeader()->setHighlightSections(false); + //最后一行拉伸填充 + tableView->horizontalHeader()->setStretchLastSection(stretchLast); + //行标题最小宽度尺寸 + tableView->horizontalHeader()->setMinimumSectionSize(0); + //行标题最小高度,等同于和默认行高一致 + tableView->horizontalHeader()->setFixedHeight(rowHeight); + //默认行高 + tableView->verticalHeader()->setDefaultSectionSize(rowHeight); + //选中时一行整体选中 + tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + //只允许选择单个 + tableView->setSelectionMode(QAbstractItemView::SingleSelection); + + //表头不可单击 +#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) + tableView->horizontalHeader()->setSectionsClickable(false); +#else + tableView->horizontalHeader()->setClickable(false); +#endif + + //鼠标按下即进入编辑模式 + if (edit) { + tableView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::DoubleClicked); + } else { + tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + } +} + +void QtHelper::openFile(const QString &fileName, const QString &msg) +{ +#ifdef __arm__ + return; +#endif + //文件不存在则不用处理 + if (!QFile(fileName).exists()) { + return; + } + if (QtHelper::showMessageBoxQuestion(msg + "成功, 确定现在就打开吗?") == QMessageBox::Yes) { + QString url = QString("file:///%1").arg(fileName); + QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode)); + } +} + +bool QtHelper::checkIniFile(const QString &iniFile) +{ + //如果配置文件大小为0,则以初始值继续运行,并生成配置文件 + QFile file(iniFile); + if (file.size() == 0) { + return false; + } + + //如果配置文件不完整,则以初始值继续运行,并生成配置文件 + if (file.open(QFile::ReadOnly)) { + bool ok = true; + while (!file.atEnd()) { + QString line = file.readLine(); + line.replace("\r", ""); + line.replace("\n", ""); + QStringList list = line.split("="); + + if (list.count() == 2) { + QString key = list.at(0); + QString value = list.at(1); + if (value.isEmpty()) { + qDebug() << TIMEMS << "ini node no value" << key; + ok = false; + break; + } + } + } + + if (!ok) { + return false; + } + } else { + return false; + } + + return true; +} + +QString QtHelper::cutString(const QString &text, int len, int left, int right, bool file, const QString &mid) +{ + //如果指定了字符串分割则表示是文件名需要去掉拓展名 + QString result = text; + if (file && result.contains(".")) { + int index = result.lastIndexOf("."); + result = result.mid(0, index); + } + + //最终字符串格式为 前缀字符...后缀字符 + if (result.length() > len) { + result = QString("%1%2%3").arg(result.left(left)).arg(mid).arg(result.right(right)); + } + + return result; +} + +QRect QtHelper::getCenterRect(const QSize &imageSize, const QRect &widgetRect, int borderWidth, int scaleMode) +{ + QSize newSize = imageSize; + QSize widgetSize = widgetRect.size() - QSize(borderWidth * 1, borderWidth * 1); + + if (scaleMode == 0) { + if (newSize.width() > widgetSize.width() || newSize.height() > widgetSize.height()) { + newSize.scale(widgetSize, Qt::KeepAspectRatio); + } + } else if (scaleMode == 1) { + newSize.scale(widgetSize, Qt::KeepAspectRatio); + } else { + newSize = widgetSize; + } + + int x = widgetRect.center().x() - newSize.width() / 2; + int y = widgetRect.center().y() - newSize.height() / 2; + //不是2的倍数需要偏移1像素 + x += (x % 2 == 0 ? 1 : 0); + y += (y % 2 == 0 ? 1 : 0); + return QRect(x, y, newSize.width(), newSize.height()); +} + +void QtHelper::getScaledImage(QImage &image, const QSize &widgetSize, int scaleMode, bool fast) +{ + Qt::TransformationMode mode = fast ? Qt::FastTransformation : Qt::SmoothTransformation; + if (scaleMode == 0) { + if (image.width() > widgetSize.width() || image.height() > widgetSize.height()) { + image = image.scaled(widgetSize, Qt::KeepAspectRatio, mode); + } + } else if (scaleMode == 1) { + image = image.scaled(widgetSize, Qt::KeepAspectRatio, mode); + } else { + image = image.scaled(widgetSize, Qt::IgnoreAspectRatio, mode); + } +} + +QString QtHelper::getTimeString(qint64 time) +{ + time = time / 1000; + QString min = QString("%1").arg(time / 60, 2, 10, QChar('0')); + QString sec = QString("%2").arg(time % 60, 2, 10, QChar('0')); + return QString("%1:%2").arg(min).arg(sec); +} + +QString QtHelper::getTimeString(QElapsedTimer timer) +{ + return QString::number((float)timer.elapsed() / 1000, 'f', 3); +} + +QString QtHelper::getSizeString(quint64 size) +{ + float num = size; + QStringList list; + list << "KB" << "MB" << "GB" << "TB"; + + QString unit("bytes"); + QStringListIterator i(list); + while (num >= 1024.0 && i.hasNext()) { + unit = i.next(); + num /= 1024.0; + } + + return QString("%1 %2").arg(QString::number(num, 'f', 2)).arg(unit); +} + +//setSystemDateTime("2022", "07", "01", "12", "22", "55"); +void QtHelper::setSystemDateTime(const QString &year, const QString &month, const QString &day, const QString &hour, const QString &min, const QString &sec) +{ +#ifdef Q_OS_WIN + QProcess p(0); + //先设置日期 + p.start("cmd"); + p.waitForStarted(); + p.write(QString("date %1-%2-%3\n").arg(year).arg(month).arg(day).toLatin1()); + p.closeWriteChannel(); + p.waitForFinished(1000); + p.close(); + //再设置时间 + p.start("cmd"); + p.waitForStarted(); + p.write(QString("time %1:%2:%3.00\n").arg(hour).arg(min).arg(sec).toLatin1()); + p.closeWriteChannel(); + p.waitForFinished(1000); + p.close(); +#else + QString cmd = QString("date %1%2%3%4%5.%6").arg(month).arg(day).arg(hour).arg(min).arg(year).arg(sec); + //设置日期时间 + system(cmd.toLatin1()); + //硬件时钟同步 + system("hwclock -w"); +#endif +} + +void QtHelper::runWithSystem(bool autoRun) +{ + QtHelper::runWithSystem(qApp->applicationName(), qApp->applicationFilePath(), autoRun); +} + +void QtHelper::runWithSystem(const QString &fileName, const QString &filePath, bool autoRun) +{ +#ifdef Q_OS_WIN + //要转换成本地文件路径(不启动则文件路径为空即可) + QSettings reg("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat); + reg.setValue(fileName, autoRun ? QDir::toNativeSeparators(filePath) : ""); +#endif +} + +void QtHelper::runBin(const QString &path, const QString &name) +{ +#ifdef Q_OS_WIN + QString cmd1 = "tasklist"; + QString cmd2 = QString("%1/%2.exe").arg(path).arg(name); +#else + QString cmd1 = "ps -aux"; + QString cmd2 = QString("%1/%2").arg(path).arg(name); +#endif + +#ifndef Q_OS_WASM + QProcess p; + p.start(cmd1); + if (p.waitForFinished()) { + QString result = p.readAll(); + if (result.contains(name)) { + return; + } + } + + //加上引号可以兼容打开带空格的目录(Program Files) + if (cmd2.contains(" ")) { + cmd2 = "\"" + cmd2 + "\""; + } + + //QProcess::execute(cmd2); + QProcess::startDetached(cmd2); +#endif +} diff --git a/tool/nettool/api/quihelper.h b/tool/nettool/api/qthelper.h similarity index 55% rename from tool/nettool/api/quihelper.h rename to tool/nettool/api/qthelper.h index 759b1a7..6562b43 100644 --- a/tool/nettool/api/quihelper.h +++ b/tool/nettool/api/qthelper.h @@ -1,14 +1,19 @@ -#ifndef QUIHELPER2_H -#define QUIHELPER2_H +#ifndef QTHELPER_H +#define QTHELPER_H #include "head.h" -class QUIHelper +class QtHelper { public: - //获取当前鼠标所在屏幕索引+尺寸 + //获取所有屏幕区域/当前鼠标所在屏幕索引/区域尺寸/缩放系数 + static QList getScreenRects(bool available = true); static int getScreenIndex(); static QRect getScreenRect(bool available = true); + static qreal getScreenRatio(bool devicePixel = false); + + //矫正当前鼠标所在屏幕居中尺寸 + static QRect checkCenterRect(QRect &rect, bool available = true); //获取桌面宽度高度+居中显示 static int deskWidth(); @@ -21,10 +26,16 @@ public: static void setFormInCenter(QWidget *form); static void showForm(QWidget *form); - //程序文件名称+当前所在路径 + //程序文件名称和当前所在路径 static QString appName(); static QString appPath(); + //程序最前面获取应用程序路径和名称 + static void getCurrentInfo(char *argv[], QString &path, QString &name); + //程序最前面读取配置文件节点的值 + static QString getIniValue(const QString &fileName, const QString &key); + static QString getIniValue(char *argv[], const QString &key, const QString &dir = QString()); + //获取本地网卡IP集合 static QStringList getLocalIPs(); @@ -43,13 +54,17 @@ public: static double getRandValue(int min, int max, bool contansMin = false, bool contansMax = false); //获取范围值随机经纬度集合 static QStringList getRandPoint(int count, float mainLng, float mainLat, float dotLng, float dotLat); + //根据旧的范围值和值计算新的范围值对应的值 + static int getRangeValue(int oldMin, int oldMax, int oldValue, int newMin, int newMax); //获取uuid static QString getUuid(); - //可执行文件目录下新建目录 - static void newDir(const QString &dirName); - //延时 - static void sleep(int msec); + //校验目录 + static void checkPath(const QString &dirName); + //通用延时函数(支持Qt4 Qt5 Qt6) + static void sleep(int msec, bool exec = true); + //检查程序是否已经运行 + static void checkRun(); //设置Qt自带样式 static void setStyle(); @@ -61,10 +76,24 @@ public: //设置翻译文件 static void setTranslator(const QString &qmFile); + //动态设置权限 + static bool checkPermission(const QString &permission); + //申请安卓权限 + static void initAndroidPermission(); + //一次性设置所有包括编码样式字体等 static void initAll(bool utf8 = true, bool style = true, int fontSize = 13); //初始化main函数最前面执行的一段代码 - static void initMain(bool on = true); + static void initMain(bool desktopSettingsAware = false, bool use96Dpi = true, bool logCritical = true); + //初始化opengl类型(1=AA_UseDesktopOpenGL 2=AA_UseOpenGLES 3=AA_UseSoftwareOpenGL) + static void initOpenGL(quint8 type = 0, bool checkCardEnable = false, bool checkVirtualSystem = false); + + //执行命令行返回执行结果 + static QString doCmd(const QString &program, const QStringList &arguments, int timeout = 1000); + //获取显卡是否被禁用 + static bool isVideoCardEnable(); + //获取是否在虚拟机环境 + static bool isVirtualSystem(); //插入消息 static QVector msgTypes; @@ -78,13 +107,13 @@ public: static void setFramelessForm(QWidget *widgetMain, bool tool = false, bool top = false, bool menu = true); //弹出框 - static int showMessageBox(const QString &info, int type = 0, int closeSec = 0, bool exec = false); + static int showMessageBox(const QString &text, int type = 0, int closeSec = 0, bool exec = false); //弹出消息框 - static void showMessageBoxInfo(const QString &info, int closeSec = 0, bool exec = false); + static void showMessageBoxInfo(const QString &text, int closeSec = 0, bool exec = false); //弹出错误框 - static void showMessageBoxError(const QString &info, int closeSec = 0, bool exec = false); + static void showMessageBoxError(const QString &text, int closeSec = 0, bool exec = false); //弹出询问框 - static int showMessageBoxQuestion(const QString &info); + static int showMessageBoxQuestion(const QString &text); //为什么还要自定义对话框因为可控宽高和汉化对应文本等 //初始化对话框文本 @@ -109,9 +138,9 @@ public: //异或加密-只支持字符,如果是中文需要将其转换base64编码 static QString getXorEncryptDecrypt(const QString &value, char key); //异或校验 - static uchar getOrCode(const QByteArray &data); + static quint8 getOrCode(const QByteArray &data); //计算校验码 - static uchar getCheckCode(const QByteArray &data); + static quint8 getCheckCode(const QByteArray &data); //初始化表格 static void initTableView(QTableView *tableView, int rowHeight = 25, @@ -124,7 +153,28 @@ public: static bool checkIniFile(const QString &iniFile); //首尾截断字符串显示 - static QString cutString(const QString &text, int len, int left, int right, const QString &mid = "..."); + static QString cutString(const QString &text, int len, int left, int right, bool file, const QString &mid = "..."); + + //传入图片尺寸和窗体区域及边框大小返回居中区域(scaleMode: 0-自动调整 1-等比缩放 2-拉伸填充) + static QRect getCenterRect(const QSize &imageSize, const QRect &widgetRect, int borderWidth = 2, int scaleMode = 0); + //传入图片尺寸和窗体尺寸及缩放策略返回合适尺寸(scaleMode: 0-自动调整 1-等比缩放 2-拉伸填充) + static void getScaledImage(QImage &image, const QSize &widgetSize, int scaleMode = 0, bool fast = true); + + //毫秒数转时间 00:00 + static QString getTimeString(qint64 time); + //用时时间转秒数 + static QString getTimeString(QElapsedTimer timer); + //文件大小转 KB MB GB TB + static QString getSizeString(quint64 size); + + //设置系统时间 + static void setSystemDateTime(const QString &year, const QString &month, const QString &day, + const QString &hour, const QString &min, const QString &sec); + //设置开机自启动 + static void runWithSystem(bool autoRun = true); + static void runWithSystem(const QString &fileName, const QString &filePath, bool autoRun = true); + //启动运行程序(已经在运行则不启动) + static void runBin(const QString &path, const QString &name); }; -#endif // QUIHELPER2_H +#endif // QTHELPER_H diff --git a/tool/netserver/api/quihelperdata.cpp b/tool/nettool/api/qthelperdata.cpp similarity index 66% rename from tool/netserver/api/quihelperdata.cpp rename to tool/nettool/api/qthelperdata.cpp index 62b7f05..5f26ee5 100644 --- a/tool/netserver/api/quihelperdata.cpp +++ b/tool/nettool/api/qthelperdata.cpp @@ -1,29 +1,29 @@ -#include "quihelperdata.h" -#include "quihelper.h" +#include "qthelperdata.h" +#include "qthelper.h" -int QUIHelperData::strHexToDecimal(const QString &strHex) +int QtHelperData::strHexToDecimal(const QString &strHex) { bool ok; return strHex.toInt(&ok, 16); } -int QUIHelperData::strDecimalToDecimal(const QString &strDecimal) +int QtHelperData::strDecimalToDecimal(const QString &strDecimal) { bool ok; return strDecimal.toInt(&ok, 10); } -int QUIHelperData::strBinToDecimal(const QString &strBin) +int QtHelperData::strBinToDecimal(const QString &strBin) { bool ok; return strBin.toInt(&ok, 2); } -QString QUIHelperData::strHexToStrBin(const QString &strHex) +QString QtHelperData::strHexToStrBin(const QString &strHex) { - uchar decimal = strHexToDecimal(strHex); + quint8 decimal = strHexToDecimal(strHex); QString bin = QString::number(decimal, 2); - uchar len = bin.length(); + quint8 len = bin.length(); if (len < 8) { for (int i = 0; i < 8 - len; ++i) { @@ -34,10 +34,10 @@ QString QUIHelperData::strHexToStrBin(const QString &strHex) return bin; } -QString QUIHelperData::decimalToStrBin1(int decimal) +QString QtHelperData::decimalToStrBin1(int decimal) { QString bin = QString::number(decimal, 2); - uchar len = bin.length(); + quint8 len = bin.length(); if (len <= 8) { for (int i = 0; i < 8 - len; ++i) { bin = "0" + bin; @@ -47,10 +47,10 @@ QString QUIHelperData::decimalToStrBin1(int decimal) return bin; } -QString QUIHelperData::decimalToStrBin2(int decimal) +QString QtHelperData::decimalToStrBin2(int decimal) { QString bin = QString::number(decimal, 2); - uchar len = bin.length(); + quint8 len = bin.length(); if (len <= 16) { for (int i = 0; i < 16 - len; ++i) { bin = "0" + bin; @@ -60,7 +60,7 @@ QString QUIHelperData::decimalToStrBin2(int decimal) return bin; } -QString QUIHelperData::decimalToStrHex(int decimal) +QString QtHelperData::decimalToStrHex(int decimal) { QString temp = QString::number(decimal, 16); if (temp.length() == 1) { @@ -70,105 +70,80 @@ QString QUIHelperData::decimalToStrHex(int decimal) return temp; } -QByteArray QUIHelperData::intToByte(int data) +QByteArray QtHelperData::intToByte(int data, bool reverse) { + quint8 data1 = (quint8)(0x000000ff & data); + quint8 data2 = (quint8)((0x0000ff00 & data) >> 8); + quint8 data3 = (quint8)((0x00ff0000 & data) >> 16); + quint8 data4 = (quint8)((0xff000000 & data) >> 24); + QByteArray result; result.resize(4); - result[3] = (uchar)(0x000000ff & data); - result[2] = (uchar)((0x0000ff00 & data) >> 8); - result[1] = (uchar)((0x00ff0000 & data) >> 16); - result[0] = (uchar)((0xff000000 & data) >> 24); + if (reverse) { + result[0] = data1; + result[1] = data2; + result[2] = data3; + result[3] = data4; + } else { + result[0] = data4; + result[1] = data3; + result[2] = data2; + result[3] = data1; + } return result; } -QByteArray QUIHelperData::intToByteRec(int data) +int QtHelperData::byteToInt(const QByteArray &data, bool reverse) { - QByteArray result; - result.resize(4); - result[0] = (uchar)(0x000000ff & data); - result[1] = (uchar)((0x0000ff00 & data) >> 8); - result[2] = (uchar)((0x00ff0000 & data) >> 16); - result[3] = (uchar)((0xff000000 & data) >> 24); + int result = 0; + if (reverse) { + result = data.at(0) & 0x000000ff; + result |= ((data.at(1) << 8) & 0x0000ff00); + result |= ((data.at(2) << 16) & 0x00ff0000); + result |= ((data.at(3) << 24) & 0xff000000); + } else { + result = data.at(3) & 0x000000ff; + result |= ((data.at(2) << 8) & 0x0000ff00); + result |= ((data.at(1) << 16) & 0x00ff0000); + result |= ((data.at(0) << 24) & 0xff000000); + } return result; } -int QUIHelperData::byteToInt(const QByteArray &data) +QByteArray QtHelperData::ushortToByte(int data, bool reverse) { - int i = data.at(3) & 0x000000ff; - i |= ((data.at(2) << 8) & 0x0000ff00); - i |= ((data.at(1) << 16) & 0x00ff0000); - i |= ((data.at(0) << 24) & 0xff000000); - return i; -} + quint8 data1 = (quint8)(0x000000ff & data); + quint8 data2 = (quint8)((0x0000ff00 & data) >> 8); -int QUIHelperData::byteToIntRec(const QByteArray &data) -{ - int i = data.at(0) & 0x000000ff; - i |= ((data.at(1) << 8) & 0x0000ff00); - i |= ((data.at(2) << 16) & 0x00ff0000); - i |= ((data.at(3) << 24) & 0xff000000); - return i; -} - -quint32 QUIHelperData::byteToUInt(const QByteArray &data) -{ - quint32 i = data.at(3) & 0x000000ff; - i |= ((data.at(2) << 8) & 0x0000ff00); - i |= ((data.at(1) << 16) & 0x00ff0000); - i |= ((data.at(0) << 24) & 0xff000000); - return i; -} - -quint32 QUIHelperData::byteToUIntRec(const QByteArray &data) -{ - quint32 i = data.at(0) & 0x000000ff; - i |= ((data.at(1) << 8) & 0x0000ff00); - i |= ((data.at(2) << 16) & 0x00ff0000); - i |= ((data.at(3) << 24) & 0xff000000); - return i; -} - -QByteArray QUIHelperData::ushortToByte(ushort data) -{ QByteArray result; result.resize(2); - result[1] = (uchar)(0x000000ff & data); - result[0] = (uchar)((0x0000ff00 & data) >> 8); + if (reverse) { + result[0] = data1; + result[1] = data2; + } else { + result[0] = data2; + result[1] = data1; + } return result; } -QByteArray QUIHelperData::ushortToByteRec(ushort data) +int QtHelperData::byteToShort(const QByteArray &data, bool reverse) { - QByteArray result; - result.resize(2); - result[0] = (uchar)(0x000000ff & data); - result[1] = (uchar)((0x0000ff00 & data) >> 8); + int result = 0; + if (reverse) { + result = data.at(0) & 0x000000ff; + result |= ((data.at(1) << 8) & 0x0000ff00); + } else { + result = data.at(1) & 0x000000ff; + result |= ((data.at(0) << 8) & 0x0000ff00); + } + if (result >= 32768) { + result = result - 65536; + } return result; } -int QUIHelperData::byteToUShort(const QByteArray &data) -{ - int i = data.at(1) & 0x000000FF; - i |= ((data.at(0) << 8) & 0x0000FF00); - if (i >= 32768) { - i = i - 65536; - } - - return i; -} - -int QUIHelperData::byteToUShortRec(const QByteArray &data) -{ - int i = data.at(0) & 0x000000FF; - i |= ((data.at(1) << 8) & 0x0000FF00); - if (i >= 32768) { - i = i - 65536; - } - - return i; -} - -QString QUIHelperData::getValue(quint8 value) +QString QtHelperData::getValue(quint8 value) { QString result = QString::number(value); if (result.length() <= 1) { @@ -177,7 +152,36 @@ QString QUIHelperData::getValue(quint8 value) return result; } -QString QUIHelperData::getXorEncryptDecrypt(const QString &value, char key) +QString QtHelperData::trimmed(const QString &text, int type) +{ + QString temp = text; + QString pattern; + if (type == -1) { + pattern = "^ +\\s*"; + } else if (type == 0) { + pattern = "\\s"; + //temp.replace(" ", ""); + } else if (type == 1) { + pattern = "\\s* +$"; + } else if (type == 2) { + temp = temp.trimmed(); + } else if (type == 3) { + temp = temp.simplified(); + } + + //调用正则表达式移除空格 + if (!pattern.isEmpty()) { +#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0)) + temp.remove(QRegularExpression(pattern)); +#else + temp.remove(QRegExp(pattern)); +#endif + } + + return temp; +} + +QString QtHelperData::getXorEncryptDecrypt(const QString &value, char key) { //矫正范围外的数据 if (key < 0 || key >= 127) { @@ -190,17 +194,16 @@ QString QUIHelperData::getXorEncryptDecrypt(const QString &value, char key) result = result.mid(8, result.length() - 9); } - int count = result.count(); - for (int i = 0; i < count; ++i) { + for (int i = 0; i < result.length(); ++i) { result[i] = QChar(result.at(i).toLatin1() ^ key); } return result; } -uchar QUIHelperData::getOrCode(const QByteArray &data) +quint8 QtHelperData::getOrCode(const QByteArray &data) { int len = data.length(); - uchar result = 0; + quint8 result = 0; for (int i = 0; i < len; ++i) { result ^= data.at(i); } @@ -208,17 +211,27 @@ uchar QUIHelperData::getOrCode(const QByteArray &data) return result; } -uchar QUIHelperData::getCheckCode(const QByteArray &data) +quint8 QtHelperData::getCheckCode(const QByteArray &data) { int len = data.length(); - uchar temp = 0; - for (uchar i = 0; i < len; ++i) { + quint8 temp = 0; + for (int i = 0; i < len; ++i) { temp += data.at(i); } return temp % 256; } +void QtHelperData::getFullData(QByteArray &buffer) +{ + //计算校验码 + quint8 checkCode = getCheckCode(buffer); + //尾部插入校验码 + buffer.append(checkCode); + //头部插入固定帧头 + buffer.insert(0, 0x16); +} + //函数功能:计算CRC16 //参数1:*data 16位CRC校验数据, //参数2:len 数据流长度 @@ -226,7 +239,7 @@ uchar QUIHelperData::getCheckCode(const QByteArray &data) //参数4:table 16位CRC查找表 //正序CRC计算 -quint16 QUIHelperData::getCrc16(quint8 *data, int len, quint16 init, const quint16 *table) +quint16 QtHelperData::getCrc16(quint8 *data, int len, quint16 init, const quint16 *table) { quint16 crc_16 = init; quint8 temp; @@ -239,7 +252,7 @@ quint16 QUIHelperData::getCrc16(quint8 *data, int len, quint16 init, const quint } //逆序CRC计算 -quint16 QUIHelperData::getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table) +quint16 QtHelperData::getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table) { quint16 crc_16 = init; quint8 temp; @@ -252,7 +265,7 @@ quint16 QUIHelperData::getCrc16Rec(quint8 *data, int len, quint16 init, const qu } //Modbus CRC16校验 -quint16 QUIHelperData::getModbus16(quint8 *data, int len) +quint16 QtHelperData::getModbus16(quint8 *data, int len) { //MODBUS CRC-16表 8005 逆序 const quint16 table_16[256] = { @@ -294,14 +307,14 @@ quint16 QUIHelperData::getModbus16(quint8 *data, int len) } //CRC16校验 -QByteArray QUIHelperData::getCrcCode(const QByteArray &data) +QByteArray QtHelperData::getCrcCode(const QByteArray &data) { quint16 result = getModbus16((quint8 *)data.data(), data.length()); - return QUIHelperData::ushortToByteRec(result); + return QtHelperData::ushortToByte(result, true); } static QMap listChar; -void QUIHelperData::initAscii() +void QtHelperData::initAscii() { //0x20为空格,空格以下都是不可见字符 if (listChar.count() == 0) { @@ -342,13 +355,13 @@ void QUIHelperData::initAscii() } } -QString QUIHelperData::byteArrayToAsciiStr(const QByteArray &data) +QString QtHelperData::byteArrayToAsciiStr(const QByteArray &data) { //先初始化字符表 initAscii(); QString temp; - int len = data.size(); + int len = data.length(); for (int i = 0; i < len; ++i) { char byte = data.at(i); QString value = listChar.value(byte); @@ -366,7 +379,7 @@ QString QUIHelperData::byteArrayToAsciiStr(const QByteArray &data) return temp.trimmed(); } -QByteArray QUIHelperData::asciiStrToByteArray(const QString &data) +QByteArray QtHelperData::asciiStrToByteArray(const QString &data) { //先初始化字符表 initAscii(); @@ -388,14 +401,14 @@ QByteArray QUIHelperData::asciiStrToByteArray(const QString &data) } //可能是纯字符串不带控制字符 - if (buffer.size() == 0) { + if (buffer.length() == 0) { buffer = data.toUtf8(); } return buffer; } -char QUIHelperData::hexStrToChar(char data) +char QtHelperData::hexStrToChar(char data) { if ((data >= '0') && (data <= '9')) { return data - 0x30; @@ -408,7 +421,7 @@ char QUIHelperData::hexStrToChar(char data) } } -QByteArray QUIHelperData::hexStrToByteArray(const QString &data) +QByteArray QtHelperData::hexStrToByteArray(const QString &data) { QByteArray senddata; int hexdata, lowhexdata; @@ -448,7 +461,7 @@ QByteArray QUIHelperData::hexStrToByteArray(const QString &data) return senddata; } -QString QUIHelperData::byteArrayToHexStr(const QByteArray &data) +QString QtHelperData::byteArrayToHexStr(const QByteArray &data) { QString temp = ""; QString hex = data.toHex(); diff --git a/tool/comtool/api/quihelperdata.h b/tool/nettool/api/qthelperdata.h similarity index 65% rename from tool/comtool/api/quihelperdata.h rename to tool/nettool/api/qthelperdata.h index b5e3815..0f649c3 100644 --- a/tool/comtool/api/quihelperdata.h +++ b/tool/nettool/api/qthelperdata.h @@ -1,9 +1,9 @@ -#ifndef QUIHELPERDATA_H -#define QUIHELPERDATA_H +#ifndef QTHELPERDATA_H +#define QTHELPERDATA_H #include -class QUIHelperData +class QtHelperData { public: //16进制字符串转10进制 @@ -22,33 +22,28 @@ public: //10进制转16进制字符串,补零. static QString decimalToStrHex(int decimal); - //int转字节数组 - static QByteArray intToByte(int data); - static QByteArray intToByteRec(int data); + //int和字节数组互转 + static QByteArray intToByte(int data, bool reverse = false); + static int byteToInt(const QByteArray &data, bool reverse = false); - //字节数组转int - static int byteToInt(const QByteArray &data); - static int byteToIntRec(const QByteArray &data); - static quint32 byteToUInt(const QByteArray &data); - static quint32 byteToUIntRec(const QByteArray &data); - - //ushort转字节数组 - static QByteArray ushortToByte(ushort data); - static QByteArray ushortToByteRec(ushort data); - - //字节数组转ushort - static int byteToUShort(const QByteArray &data); - static int byteToUShortRec(const QByteArray &data); + //ushort和字节数组互转 + static QByteArray ushortToByte(int data, bool reverse = false); + static int byteToShort(const QByteArray &data, bool reverse = false); //字符串补全 static QString getValue(quint8 value); + //字符串去空格 -1=移除左侧空格 0=移除所有空格 1=移除右侧空格 2=移除首尾空格 3=首尾清除中间留一个空格 + static QString trimmed(const QString &text, int type); //异或加密-只支持字符,如果是中文需要将其转换base64编码 static QString getXorEncryptDecrypt(const QString &value, char key); //异或校验 - static uchar getOrCode(const QByteArray &data); - //计算校验码 - static uchar getCheckCode(const QByteArray &data); + static quint8 getOrCode(const QByteArray &data); + + //公司专用-计算校验码 + static quint8 getCheckCode(const QByteArray &data); + //公司专用-加上桢头和校验码完整数据 + static void getFullData(QByteArray &buffer); //CRC校验 static quint16 getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table); @@ -67,4 +62,4 @@ public: static QString byteArrayToHexStr(const QByteArray &data); }; -#endif // QUIHELPERDATA_H +#endif // QTHELPERDATA_H diff --git a/tool/nettool/api/quihelper.cpp b/tool/nettool/api/quihelper.cpp deleted file mode 100644 index 788147d..0000000 --- a/tool/nettool/api/quihelper.cpp +++ /dev/null @@ -1,818 +0,0 @@ -#include "quihelper.h" -#include "qnetworkinterface.h" -#include "qnetworkproxy.h" - -#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz")) -int QUIHelper::getScreenIndex() -{ - //需要对多个屏幕进行处理 - int screenIndex = 0; -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - int screenCount = qApp->screens().count(); -#else - int screenCount = qApp->desktop()->screenCount(); -#endif - - if (screenCount > 1) { - //找到当前鼠标所在屏幕 - QPoint pos = QCursor::pos(); - for (int i = 0; i < screenCount; ++i) { -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - if (qApp->screens().at(i)->geometry().contains(pos)) { -#else - if (qApp->desktop()->screenGeometry(i).contains(pos)) { -#endif - screenIndex = i; - break; - } - } - } - return screenIndex; -} - -QRect QUIHelper::getScreenRect(bool available) -{ - QRect rect; - int screenIndex = QUIHelper::getScreenIndex(); - if (available) { -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - rect = qApp->screens().at(screenIndex)->availableGeometry(); -#else - rect = qApp->desktop()->availableGeometry(screenIndex); -#endif - } else { -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - rect = qApp->screens().at(screenIndex)->geometry(); -#else - rect = qApp->desktop()->screenGeometry(screenIndex); -#endif - } - return rect; -} - -int QUIHelper::deskWidth() -{ - return getScreenRect().width(); -} - -int QUIHelper::deskHeight() -{ - return getScreenRect().height(); -} - -QSize QUIHelper::deskSize() -{ - return getScreenRect().size(); -} - -QWidget *QUIHelper::centerBaseForm = 0; -void QUIHelper::setFormInCenter(QWidget *form) -{ - int formWidth = form->width(); - int formHeight = form->height(); - - //如果=0表示采用系统桌面屏幕为参照 - QRect rect; - if (centerBaseForm == 0) { - rect = getScreenRect(); - } else { - rect = centerBaseForm->geometry(); - } - - int deskWidth = rect.width(); - int deskHeight = rect.height(); - QPoint movePoint(deskWidth / 2 - formWidth / 2 + rect.x(), deskHeight / 2 - formHeight / 2 + rect.y()); - form->move(movePoint); -} - -void QUIHelper::showForm(QWidget *form) -{ - setFormInCenter(form); - form->show(); - - //判断宽高是否超过了屏幕分辨率,超过了则最大化显示 - //qDebug() << TIMEMS << form->size() << deskSize(); - if (form->width() + 20 > deskWidth() || form->height() + 50 > deskHeight()) { - QMetaObject::invokeMethod(form, "showMaximized", Qt::QueuedConnection); - } -} - -QString QUIHelper::appName() -{ - //没有必要每次都获取,只有当变量为空时才去获取一次 - static QString name; - if (name.isEmpty()) { - name = qApp->applicationFilePath(); - //下面的方法主要为了过滤安卓的路径 lib程序名_armeabi-v7a - QStringList list = name.split("/"); - name = list.at(list.count() - 1).split(".").at(0); - name.replace("_armeabi-v7a", ""); - } - - return name; -} - -QString QUIHelper::appPath() -{ - static QString path; - if (path.isEmpty()) { -#ifdef Q_OS_ANDROID - //默认安卓根目录 - path = "/storage/emulated/0"; - //带上程序名称作为目录 前面加个0方便排序 - path = path + "/0" + appName(); -#else - path = qApp->applicationDirPath(); -#endif - } - - return path; -} - -QStringList QUIHelper::getLocalIPs() -{ - static QStringList ips; - if (ips.count() == 0) { -#ifdef Q_OS_WASM - ips << "127.0.0.1"; -#else - QList netInterfaces = QNetworkInterface::allInterfaces(); - foreach (const QNetworkInterface &netInterface, netInterfaces) { - //移除虚拟机和抓包工具的虚拟网卡 - QString humanReadableName = netInterface.humanReadableName().toLower(); - if (humanReadableName.startsWith("vmware network adapter") || humanReadableName.startsWith("npcap loopback adapter")) { - continue; - } - - //过滤当前网络接口 - bool flag = (netInterface.flags() == (QNetworkInterface::IsUp | QNetworkInterface::IsRunning | QNetworkInterface::CanBroadcast | QNetworkInterface::CanMulticast)); - if (!flag) { - continue; - } - - QList addrs = netInterface.addressEntries(); - foreach (QNetworkAddressEntry addr, addrs) { - //只取出IPV4的地址 - if (addr.ip().protocol() != QAbstractSocket::IPv4Protocol) { - continue; - } - - QString ip4 = addr.ip().toString(); - if (ip4 != "127.0.0.1") { - ips << ip4; - } - } - } -#endif - } - - return ips; -} - -QList QUIHelper::colors = QList(); -QList QUIHelper::getColorList() -{ - //备用颜色集合 可以自行添加 - if (colors.count() == 0) { - colors << QColor(0, 176, 180) << QColor(0, 113, 193) << QColor(255, 192, 0); - colors << QColor(72, 103, 149) << QColor(185, 87, 86) << QColor(0, 177, 125); - colors << QColor(214, 77, 84) << QColor(71, 164, 233) << QColor(34, 163, 169); - colors << QColor(59, 123, 156) << QColor(162, 121, 197) << QColor(72, 202, 245); - colors << QColor(0, 150, 121) << QColor(111, 9, 176) << QColor(250, 170, 20); - } - - return colors; -} - -QStringList QUIHelper::getColorNames() -{ - QList colors = getColorList(); - QStringList colorNames; - foreach (QColor color, colors) { - colorNames << color.name(); - } - return colorNames; -} - -QColor QUIHelper::getRandColor() -{ - QList colors = getColorList(); - int index = getRandValue(0, colors.count(), true); - return colors.at(index); -} - -void QUIHelper::initRand() -{ - //初始化随机数种子 - QTime t = QTime::currentTime(); - srand(t.msec() + t.second() * 1000); -} - -float QUIHelper::getRandFloat(float min, float max) -{ - double diff = fabs(max - min); - double value = (double)(rand() % 100) / 100; - value = min + value * diff; - return value; -} - -double QUIHelper::getRandValue(int min, int max, bool contansMin, bool contansMax) -{ - int value; -#if (QT_VERSION <= QT_VERSION_CHECK(5,10,0)) - //通用公式 a是起始值,n是整数的范围 - //int value = a + rand() % n; - if (contansMin) { - if (contansMax) { - value = min + 0 + (rand() % (max - min + 1)); - } else { - value = min + 0 + (rand() % (max - min + 0)); - } - } else { - if (contansMax) { - value = min + 1 + (rand() % (max - min + 0)); - } else { - value = min + 1 + (rand() % (max - min - 1)); - } - } -#else - if (contansMin) { - if (contansMax) { - value = QRandomGenerator::global()->bounded(min + 0, max + 1); - } else { - value = QRandomGenerator::global()->bounded(min + 0, max + 0); - } - } else { - if (contansMax) { - value = QRandomGenerator::global()->bounded(min + 1, max + 1); - } else { - value = QRandomGenerator::global()->bounded(min + 1, max + 0); - } - } -#endif - return value; -} - -QStringList QUIHelper::getRandPoint(int count, float mainLng, float mainLat, float dotLng, float dotLat) -{ - //随机生成点坐标 - QStringList points; - for (int i = 0; i < count; ++i) { - //0.00881415 0.000442928 -#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0)) - float lngx = QRandomGenerator::global()->bounded(dotLng); - float latx = QRandomGenerator::global()->bounded(dotLat); -#else - float lngx = getRandFloat(dotLng / 10, dotLng); - float latx = getRandFloat(dotLat / 10, dotLat); -#endif - //需要先用精度转换成字符串 - QString lng2 = QString::number(mainLng + lngx, 'f', 8); - QString lat2 = QString::number(mainLat + latx, 'f', 8); - QString point = QString("%1,%2").arg(lng2).arg(lat2); - points << point; - } - - return points; -} - -QString QUIHelper::getUuid() -{ - QString uuid = QUuid::createUuid().toString(); - uuid.replace("{", ""); - uuid.replace("}", ""); - return uuid; -} - -void QUIHelper::newDir(const QString &dirName) -{ - QString strDir = dirName; - - //如果路径中包含斜杠字符则说明是绝对路径 - //linux系统路径字符带有 / windows系统 路径字符带有 :/ - if (!strDir.startsWith("/") && !strDir.contains(":/")) { - strDir = QString("%1/%2").arg(QUIHelper::appPath()).arg(strDir); - } - - QDir dir(strDir); - if (!dir.exists()) { - dir.mkpath(strDir); - } -} - -void QUIHelper::sleep(int msec) -{ - if (msec <= 0) { - return; - } - -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - QThread::msleep(msec); -#else - QTime endTime = QTime::currentTime().addMSecs(msec); - while (QTime::currentTime() < endTime) { - QCoreApplication::processEvents(QEventLoop::AllEvents, 100); - } -#endif -} - -void QUIHelper::setStyle() -{ - //打印下所有内置风格的名字 - qDebug() << TIMEMS << "QStyleFactory::keys" << QStyleFactory::keys(); - //设置内置风格 -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - qApp->setStyle(QStyleFactory::create("Fusion")); -#else - qApp->setStyle(QStyleFactory::create("Cleanlooks")); -#endif - - //设置指定颜色 - QPalette palette; - palette.setBrush(QPalette::Window, QColor("#F0F0F0")); - qApp->setPalette(palette); -} - -QFont QUIHelper::addFont(const QString &fontFile, const QString &fontName) -{ - //判断图形字体是否存在,不存在则加入 - QFontDatabase fontDb; - if (!fontDb.families().contains(fontName)) { - int fontId = fontDb.addApplicationFont(fontFile); - QStringList listName = fontDb.applicationFontFamilies(fontId); - if (listName.count() == 0) { - qDebug() << QString("load %1 error").arg(fontName); - } - } - - //再次判断是否包含字体名称防止加载失败 - QFont font; - if (fontDb.families().contains(fontName)) { - font = QFont(fontName); -#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0)) - font.setHintingPreference(QFont::PreferNoHinting); -#endif - } - - return font; -} - -void QUIHelper::setFont(int fontSize) -{ -#ifdef rk3399 - return; -#endif - //安卓套件在有些手机上默认字体不好看需要主动设置字体 - //网页套件需要主动加载中文字体才能正常显示中文 -#if (defined Q_OS_ANDROID) || (defined Q_OS_WASM) - QString fontFile = ":/font/DroidSansFallback.ttf"; - QString fontName = "Droid Sans Fallback"; - qApp->setFont(addFont(fontFile, fontName)); - return; -#endif - -#ifdef __arm__ - fontSize = 25; -#endif -#ifdef Q_OS_ANDROID - fontSize = 15; -#endif - - QFont font; - font.setFamily("MicroSoft Yahei"); - font.setPixelSize(fontSize); - qApp->setFont(font); -} - -void QUIHelper::setCode(bool utf8) -{ -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - //如果想要控制台打印信息中文正常就注释掉这个设置 - if (utf8) { - QTextCodec *codec = QTextCodec::codecForName("utf-8"); - QTextCodec::setCodecForLocale(codec); - } -#else -#if _MSC_VER - QTextCodec *codec = QTextCodec::codecForName("gbk"); -#else - QTextCodec *codec = QTextCodec::codecForName("utf-8"); -#endif - QTextCodec::setCodecForLocale(codec); - QTextCodec::setCodecForCStrings(codec); - QTextCodec::setCodecForTr(codec); -#endif -} - -void QUIHelper::setTranslator(const QString &qmFile) -{ - //过滤下不存在的就不用设置了 - if (!QFile(qmFile).exists()) { - return; - } - - QTranslator *translator = new QTranslator(qApp); - if (translator->load(qmFile)) { - qApp->installTranslator(translator); - } -} - -void QUIHelper::initAll(bool utf8, bool style, int fontSize) -{ - //初始化随机数种子 - QUIHelper::initRand(); - //设置编码 - QUIHelper::setCode(utf8); - //设置样式风格 - if (style) { - QUIHelper::setStyle(); - } - //设置字体 - QUIHelper::setFont(fontSize); - //设置翻译文件支持多个 - QUIHelper::setTranslator(":/qm/widgets.qm"); - QUIHelper::setTranslator(":/qm/qt_zh_CN.qm"); - QUIHelper::setTranslator(":/qm/designer_zh_CN.qm"); - //设置不使用本地系统环境代理配置 - QNetworkProxyFactory::setUseSystemConfiguration(false); -} - -void QUIHelper::initMain(bool on) -{ - //设置是否应用操作系统设置比如字体 - QApplication::setDesktopSettingsAware(on); - -#ifdef Q_OS_ANDROID -#if (QT_VERSION >= QT_VERSION_CHECK(5,6,0)) - //开启高分屏缩放支持 - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif -#else -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - //不应用任何缩放 - QApplication::setAttribute(Qt::AA_Use96Dpi); -#endif -#endif - -#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) - //高分屏缩放策略 - QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor); -#endif - -#if (QT_VERSION >= QT_VERSION_CHECK(5,4,0)) - //设置opengl模式 AA_UseDesktopOpenGL(默认) AA_UseOpenGLES AA_UseSoftwareOpenGL - //在一些很旧的设备上或者对opengl支持很低的设备上需要使用AA_UseOpenGLES表示禁用硬件加速 - //如果开启的是AA_UseOpenGLES则无法使用硬件加速比如ffmpeg的dxva2 - //QApplication::setAttribute(Qt::AA_UseOpenGLES); - //设置opengl共享上下文 - QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); -#endif -} - -QVector QUIHelper::msgTypes = QVector() << 0 << 1 << 2 << 3 << 4; -QVector QUIHelper::msgKeys = QVector() << "发送" << "接收" << "解析" << "错误" << "提示"; -QVector QUIHelper::msgColors = QVector() << QColor("#3BA372") << QColor("#EE6668") << QColor("#9861B4") << QColor("#FA8359") << QColor("#22A3A9"); -QString QUIHelper::appendMsg(QTextEdit *textEdit, int type, const QString &data, int maxCount, int ¤tCount, bool clear, bool pause) -{ - if (clear) { - textEdit->clear(); - currentCount = 0; - return QString(); - } - - if (pause) { - return QString(); - } - - if (currentCount >= maxCount) { - textEdit->clear(); - currentCount = 0; - } - - //不同类型不同颜色显示 - QString strType; - int index = msgTypes.indexOf(type); - if (index >= 0) { - strType = msgKeys.at(index); - textEdit->setTextColor(msgColors.at(index)); - } - - //过滤回车换行符 - QString strData = data; - strData.replace("\r", ""); - strData.replace("\n", ""); - strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData); - textEdit->append(strData); - currentCount++; - return strData; -} - -void QUIHelper::setFramelessForm(QWidget *widgetMain, bool tool, bool top, bool menu) -{ - widgetMain->setProperty("form", true); - widgetMain->setProperty("canMove", true); - - //根据设定逐个追加属性 -#ifdef __arm__ - widgetMain->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); -#else - widgetMain->setWindowFlags(Qt::FramelessWindowHint); -#endif - if (tool) { - widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::Tool); - } - if (top) { - widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowStaysOnTopHint); - } - if (menu) { - //如果是其他系统比如neokylin会产生系统边框 -#ifdef Q_OS_WIN - widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint); -#endif - } -} - -int QUIHelper::showMessageBox(const QString &info, int type, int closeSec, bool exec) -{ - int result = 0; - if (type == 0) { - showMessageBoxInfo(info, closeSec, exec); - } else if (type == 1) { - showMessageBoxError(info, closeSec, exec); - } else if (type == 2) { - result = showMessageBoxQuestion(info); - } - - return result; -} - -void QUIHelper::showMessageBoxInfo(const QString &info, int closeSec, bool exec) -{ - QMessageBox box(QMessageBox::Information, "提示", info); - box.setStandardButtons(QMessageBox::Yes); - box.setButtonText(QMessageBox::Yes, QString("确 定")); - box.exec(); - //QMessageBox::information(0, "提示", info, QMessageBox::Yes); -} - -void QUIHelper::showMessageBoxError(const QString &info, int closeSec, bool exec) -{ - QMessageBox box(QMessageBox::Critical, "错误", info); - box.setStandardButtons(QMessageBox::Yes); - box.setButtonText(QMessageBox::Yes, QString("确 定")); - box.exec(); - //QMessageBox::critical(0, "错误", info, QMessageBox::Yes); -} - -int QUIHelper::showMessageBoxQuestion(const QString &info) -{ - QMessageBox box(QMessageBox::Question, "询问", info); - box.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - box.setButtonText(QMessageBox::Yes, QString("确 定")); - box.setButtonText(QMessageBox::No, QString("取 消")); - return box.exec(); - //return QMessageBox::question(0, "询问", info, QMessageBox::Yes | QMessageBox::No); -} - -void QUIHelper::initDialog(QFileDialog *dialog, const QString &title, const QString &acceptName, - const QString &dirName, bool native, int width, int height) -{ - //设置标题 - dialog->setWindowTitle(title); - //设置标签文本 - dialog->setLabelText(QFileDialog::Accept, acceptName); - dialog->setLabelText(QFileDialog::Reject, "取消(&C)"); - dialog->setLabelText(QFileDialog::LookIn, "查看"); - dialog->setLabelText(QFileDialog::FileName, "名称"); - dialog->setLabelText(QFileDialog::FileType, "类型"); - - //设置默认显示目录 - if (!dirName.isEmpty()) { - dialog->setDirectory(dirName); - } - - //设置对话框宽高 - if (width > 0 && height > 0) { -#ifdef Q_OS_ANDROID - bool horizontal = (QUIHelper::deskWidth() > QUIHelper::deskHeight()); - if (horizontal) { - width = QUIHelper::deskWidth() / 2; - height = QUIHelper::deskHeight() - 50; - } else { - width = QUIHelper::deskWidth() - 10; - height = QUIHelper::deskHeight() / 2; - } -#endif - dialog->setFixedSize(width, height); - } - - //设置是否采用本地对话框 - dialog->setOption(QFileDialog::DontUseNativeDialog, !native); - //设置只读可以取消右上角的新建按钮 - //dialog->setReadOnly(true); -} - -QString QUIHelper::getDialogResult(QFileDialog *dialog) -{ - QString result; - if (dialog->exec() == QFileDialog::Accepted) { - result = dialog->selectedFiles().first(); - } - return result; -} - -QString QUIHelper::getOpenFileName(const QString &filter, const QString &dirName, const QString &fileName, - bool native, int width, int height) -{ - QFileDialog dialog; - initDialog(&dialog, "打开文件", "选择(&S)", dirName, native, width, height); - - //设置文件类型 - if (!filter.isEmpty()) { - dialog.setNameFilter(filter); - } - - //设置默认文件名称 - dialog.selectFile(fileName); - return getDialogResult(&dialog); -} - -QString QUIHelper::getSaveFileName(const QString &filter, const QString &dirName, const QString &fileName, - bool native, int width, int height) -{ - QFileDialog dialog; - initDialog(&dialog, "保存文件", "保存(&S)", dirName, native, width, height); - - //设置文件类型 - if (!filter.isEmpty()) { - dialog.setNameFilter(filter); - } - - //设置默认文件名称 - dialog.selectFile(fileName); - //设置模态类型允许输入 - dialog.setWindowModality(Qt::WindowModal); - //设置置顶显示 - dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint); - return getDialogResult(&dialog); -} - -QString QUIHelper::getExistingDirectory(const QString &dirName, bool native, int width, int height) -{ - QFileDialog dialog; - initDialog(&dialog, "选择目录", "选择(&S)", dirName, native, width, height); - dialog.setOption(QFileDialog::ReadOnly); - //设置只显示目录 -#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) - dialog.setFileMode(QFileDialog::DirectoryOnly); -#endif - dialog.setOption(QFileDialog::ShowDirsOnly); - return getDialogResult(&dialog); -} - -QString QUIHelper::getXorEncryptDecrypt(const QString &value, char key) -{ - //矫正范围外的数据 - if (key < 0 || key >= 127) { - key = 127; - } - - //大概从5.9版本输出的加密密码字符串前面会加上 @String 字符 - QString result = value; - if (result.startsWith("@String")) { - result = result.mid(8, result.length() - 9); - } - - int count = result.count(); - for (int i = 0; i < count; ++i) { - result[i] = QChar(result.at(i).toLatin1() ^ key); - } - return result; -} - -uchar QUIHelper::getOrCode(const QByteArray &data) -{ - int len = data.length(); - uchar result = 0; - for (int i = 0; i < len; ++i) { - result ^= data.at(i); - } - - return result; -} - -uchar QUIHelper::getCheckCode(const QByteArray &data) -{ - int len = data.length(); - uchar temp = 0; - for (uchar i = 0; i < len; ++i) { - temp += data.at(i); - } - - return temp % 256; -} - -void QUIHelper::initTableView(QTableView *tableView, int rowHeight, bool headVisible, bool edit, bool stretchLast) -{ - //设置弱属性用于应用qss特殊样式 - tableView->setProperty("model", true); - //取消自动换行 - tableView->setWordWrap(false); - //超出文本不显示省略号 - tableView->setTextElideMode(Qt::ElideNone); - //奇数偶数行颜色交替 - tableView->setAlternatingRowColors(false); - //垂直表头是否可见 - tableView->verticalHeader()->setVisible(headVisible); - //选中一行表头是否加粗 - tableView->horizontalHeader()->setHighlightSections(false); - //最后一行拉伸填充 - tableView->horizontalHeader()->setStretchLastSection(stretchLast); - //行标题最小宽度尺寸 - tableView->horizontalHeader()->setMinimumSectionSize(0); - //行标题最小高度,等同于和默认行高一致 - tableView->horizontalHeader()->setFixedHeight(rowHeight); - //默认行高 - tableView->verticalHeader()->setDefaultSectionSize(rowHeight); - //选中时一行整体选中 - tableView->setSelectionBehavior(QAbstractItemView::SelectRows); - //只允许选择单个 - tableView->setSelectionMode(QAbstractItemView::SingleSelection); - - //表头不可单击 -#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - tableView->horizontalHeader()->setSectionsClickable(false); -#else - tableView->horizontalHeader()->setClickable(false); -#endif - - //鼠标按下即进入编辑模式 - if (edit) { - tableView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::DoubleClicked); - } else { - tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); - } -} - -void QUIHelper::openFile(const QString &fileName, const QString &msg) -{ -#ifdef __arm__ - return; -#endif - //文件不存在则不用处理 - if (!QFile(fileName).exists()) { - return; - } - if (QUIHelper::showMessageBoxQuestion(msg + "成功, 确定现在就打开吗?") == QMessageBox::Yes) { - QString url = QString("file:///%1").arg(fileName); - QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode)); - } -} - -bool QUIHelper::checkIniFile(const QString &iniFile) -{ - //如果配置文件大小为0,则以初始值继续运行,并生成配置文件 - QFile file(iniFile); - if (file.size() == 0) { - return false; - } - - //如果配置文件不完整,则以初始值继续运行,并生成配置文件 - if (file.open(QFile::ReadOnly)) { - bool ok = true; - while (!file.atEnd()) { - QString line = file.readLine(); - line.replace("\r", ""); - line.replace("\n", ""); - QStringList list = line.split("="); - - if (list.count() == 2) { - QString key = list.at(0); - QString value = list.at(1); - if (value.isEmpty()) { - qDebug() << TIMEMS << "ini node no value" << key; - ok = false; - break; - } - } - } - - if (!ok) { - return false; - } - } else { - return false; - } - - return true; -} - -QString QUIHelper::cutString(const QString &text, int len, int left, int right, const QString &mid) -{ - //如果是文件名则取文件名的前字符+末尾字符+去掉拓展名 - QString result = text.split(".").first(); - if (result.length() > len) { - result = QString("%1%2%3").arg(result.left(left)).arg(mid).arg(result.right(right)); - } - return result; -} diff --git a/tool/nettool/api/tcpclient.cpp b/tool/nettool/api/tcpclient.cpp index 0610331..29930f5 100644 --- a/tool/nettool/api/tcpclient.cpp +++ b/tool/nettool/api/tcpclient.cpp @@ -1,6 +1,6 @@ #include "tcpclient.h" -#include "quihelper.h" -#include "quihelperdata.h" +#include "qthelper.h" +#include "qthelperdata.h" TcpClient::TcpClient(QTcpSocket *socket, QObject *parent) : QObject(parent) { @@ -49,9 +49,9 @@ void TcpClient::slot_readData() QString buffer; if (AppConfig::HexReceiveTcpServer) { - buffer = QUIHelperData::byteArrayToHexStr(data); + buffer = QtHelperData::byteArrayToHexStr(data); } else if (AppConfig::AsciiTcpServer) { - buffer = QUIHelperData::byteArrayToAsciiStr(data); + buffer = QtHelperData::byteArrayToAsciiStr(data); } else { buffer = QString(data); } @@ -74,9 +74,9 @@ void TcpClient::sendData(const QString &data) { QByteArray buffer; if (AppConfig::HexSendTcpServer) { - buffer = QUIHelperData::hexStrToByteArray(data); + buffer = QtHelperData::hexStrToByteArray(data); } else if (AppConfig::AsciiTcpServer) { - buffer = QUIHelperData::asciiStrToByteArray(data); + buffer = QtHelperData::asciiStrToByteArray(data); } else { buffer = data.toUtf8(); } diff --git a/tool/nettool/api/tcpserver.cpp b/tool/nettool/api/tcpserver.cpp index 0fbcdaa..347c8dc 100644 --- a/tool/nettool/api/tcpserver.cpp +++ b/tool/nettool/api/tcpserver.cpp @@ -1,5 +1,5 @@ #include "tcpserver.h" -#include "quihelper.h" +#include "qthelper.h" TcpServer::TcpServer(QObject *parent) : QTcpServer(parent) { diff --git a/tool/nettool/api/webclient.cpp b/tool/nettool/api/webclient.cpp index 3cc6278..3276dff 100644 --- a/tool/nettool/api/webclient.cpp +++ b/tool/nettool/api/webclient.cpp @@ -1,6 +1,6 @@ #include "webclient.h" -#include "quihelper.h" -#include "quihelperdata.h" +#include "qthelper.h" +#include "qthelperdata.h" WebClient::WebClient(QWebSocket *socket, QObject *parent) : QObject(parent) { @@ -63,7 +63,7 @@ void WebClient::binaryFrameReceived(const QByteArray &data, bool isLastFrame) { QString buffer; if (AppConfig::HexReceiveWebClient) { - buffer = QUIHelperData::byteArrayToHexStr(data); + buffer = QtHelperData::byteArrayToHexStr(data); } else { buffer = QString(data); } @@ -85,7 +85,7 @@ void WebClient::sendData(const QString &data) { QByteArray buffer; if (AppConfig::HexSendWebServer) { - buffer = QUIHelperData::hexStrToByteArray(data); + buffer = QtHelperData::hexStrToByteArray(data); } else { buffer = data.toUtf8(); } diff --git a/tool/nettool/api/webserver.cpp b/tool/nettool/api/webserver.cpp index 4d8263a..0df95cb 100644 --- a/tool/nettool/api/webserver.cpp +++ b/tool/nettool/api/webserver.cpp @@ -1,5 +1,5 @@ #include "webserver.h" -#include "quihelper.h" +#include "qthelper.h" WebServer::WebServer(const QString &serverName, SslMode secureMode, QObject *parent) : QWebSocketServer(serverName, secureMode, parent) { diff --git a/tool/nettool/form/frmmain.cpp b/tool/nettool/form/frmmain.cpp index 39d771a..d1d0c05 100644 --- a/tool/nettool/form/frmmain.cpp +++ b/tool/nettool/form/frmmain.cpp @@ -1,6 +1,6 @@ #include "frmmain.h" #include "ui_frmmain.h" -#include "quihelper.h" +#include "qthelper.h" #include "frmtcpclient.h" #include "frmtcpserver.h" diff --git a/tool/nettool/form/frmtcpclient.cpp b/tool/nettool/form/frmtcpclient.cpp index 3fa75a8..c0004bc 100644 --- a/tool/nettool/form/frmtcpclient.cpp +++ b/tool/nettool/form/frmtcpclient.cpp @@ -1,7 +1,7 @@ #include "frmtcpclient.h" #include "ui_frmtcpclient.h" -#include "quihelper.h" -#include "quihelperdata.h" +#include "qthelper.h" +#include "qthelperdata.h" frmTcpClient::frmTcpClient(QWidget *parent) : QWidget(parent), ui(new Ui::frmTcpClient) { @@ -199,9 +199,9 @@ void frmTcpClient::readData() QString buffer; if (AppConfig::HexReceiveTcpClient) { - buffer = QUIHelperData::byteArrayToHexStr(data); + buffer = QtHelperData::byteArrayToHexStr(data); } else if (AppConfig::AsciiTcpClient) { - buffer = QUIHelperData::byteArrayToAsciiStr(data); + buffer = QtHelperData::byteArrayToAsciiStr(data); } else { buffer = QString(data); } @@ -224,9 +224,9 @@ void frmTcpClient::sendData(const QString &data) { QByteArray buffer; if (AppConfig::HexSendTcpClient) { - buffer = QUIHelperData::hexStrToByteArray(data); + buffer = QtHelperData::hexStrToByteArray(data); } else if (AppConfig::AsciiTcpClient) { - buffer = QUIHelperData::asciiStrToByteArray(data); + buffer = QtHelperData::asciiStrToByteArray(data); } else { buffer = data.toUtf8(); } diff --git a/tool/nettool/form/frmtcpserver.cpp b/tool/nettool/form/frmtcpserver.cpp index 0cfa9f8..9fa55c2 100644 --- a/tool/nettool/form/frmtcpserver.cpp +++ b/tool/nettool/form/frmtcpserver.cpp @@ -1,6 +1,6 @@ #include "frmtcpserver.h" #include "ui_frmtcpserver.h" -#include "quihelper.h" +#include "qthelper.h" frmTcpServer::frmTcpServer(QWidget *parent) : QWidget(parent), ui(new Ui::frmTcpServer) { diff --git a/tool/nettool/form/frmudpclient.cpp b/tool/nettool/form/frmudpclient.cpp index f743cc2..15621a7 100644 --- a/tool/nettool/form/frmudpclient.cpp +++ b/tool/nettool/form/frmudpclient.cpp @@ -1,7 +1,7 @@ #include "frmudpclient.h" #include "ui_frmudpclient.h" -#include "quihelper.h" -#include "quihelperdata.h" +#include "qthelper.h" +#include "qthelperdata.h" frmUdpClient::frmUdpClient(QWidget *parent) : QWidget(parent), ui(new Ui::frmUdpClient) { @@ -182,9 +182,9 @@ void frmUdpClient::readData() socket->readDatagram(data.data(), data.size(), &host, &port); if (AppConfig::HexReceiveUdpClient) { - buffer = QUIHelperData::byteArrayToHexStr(data); + buffer = QtHelperData::byteArrayToHexStr(data); } else if (AppConfig::AsciiUdpClient) { - buffer = QUIHelperData::byteArrayToAsciiStr(data); + buffer = QtHelperData::byteArrayToAsciiStr(data); } else { buffer = QString(data); } @@ -214,9 +214,9 @@ void frmUdpClient::sendData(const QString &ip, int port, const QString &data) { QByteArray buffer; if (AppConfig::HexSendUdpClient) { - buffer = QUIHelperData::hexStrToByteArray(data); + buffer = QtHelperData::hexStrToByteArray(data); } else if (AppConfig::AsciiUdpClient) { - buffer = QUIHelperData::asciiStrToByteArray(data); + buffer = QtHelperData::asciiStrToByteArray(data); } else { buffer = data.toUtf8(); } diff --git a/tool/nettool/form/frmudpserver.cpp b/tool/nettool/form/frmudpserver.cpp index 7a01834..7f5625e 100644 --- a/tool/nettool/form/frmudpserver.cpp +++ b/tool/nettool/form/frmudpserver.cpp @@ -1,7 +1,7 @@ #include "frmudpserver.h" #include "ui_frmudpserver.h" -#include "quihelper.h" -#include "quihelperdata.h" +#include "qthelper.h" +#include "qthelperdata.h" frmUdpServer::frmUdpServer(QWidget *parent) : QWidget(parent), ui(new Ui::frmUdpServer) { @@ -179,9 +179,9 @@ void frmUdpServer::readData() socket->readDatagram(data.data(), data.size(), &host, &port); if (AppConfig::HexReceiveUdpServer) { - buffer = QUIHelperData::byteArrayToHexStr(data); + buffer = QtHelperData::byteArrayToHexStr(data); } else if (AppConfig::AsciiUdpServer) { - buffer = QUIHelperData::byteArrayToAsciiStr(data); + buffer = QtHelperData::byteArrayToAsciiStr(data); } else { buffer = QString(data); } @@ -224,9 +224,9 @@ void frmUdpServer::sendData(const QString &ip, int port, const QString &data) { QByteArray buffer; if (AppConfig::HexSendUdpServer) { - buffer = QUIHelperData::hexStrToByteArray(data); + buffer = QtHelperData::hexStrToByteArray(data); } else if (AppConfig::AsciiUdpServer) { - buffer = QUIHelperData::asciiStrToByteArray(data); + buffer = QtHelperData::asciiStrToByteArray(data); } else { buffer = data.toUtf8(); } diff --git a/tool/nettool/form/frmwebclient.cpp b/tool/nettool/form/frmwebclient.cpp index 5a3a865..d949868 100644 --- a/tool/nettool/form/frmwebclient.cpp +++ b/tool/nettool/form/frmwebclient.cpp @@ -1,7 +1,7 @@ #include "frmwebclient.h" #include "ui_frmwebclient.h" -#include "quihelper.h" -#include "quihelperdata.h" +#include "qthelper.h" +#include "qthelperdata.h" frmWebClient::frmWebClient(QWidget *parent) : QWidget(parent), ui(new Ui::frmWebClient) { @@ -187,7 +187,7 @@ void frmWebClient::sendData(const QString &data) { QByteArray buffer; if (AppConfig::HexSendWebClient) { - buffer = QUIHelperData::hexStrToByteArray(data); + buffer = QtHelperData::hexStrToByteArray(data); } else { buffer = data.toUtf8(); } @@ -222,7 +222,7 @@ void frmWebClient::binaryFrameReceived(const QByteArray &data, bool isLastFrame) { QString buffer; if (AppConfig::HexReceiveWebClient) { - buffer = QUIHelperData::byteArrayToHexStr(data); + buffer = QtHelperData::byteArrayToHexStr(data); } else { buffer = QString(data); } diff --git a/tool/nettool/form/frmwebserver.cpp b/tool/nettool/form/frmwebserver.cpp index 05d856b..cf64127 100644 --- a/tool/nettool/form/frmwebserver.cpp +++ b/tool/nettool/form/frmwebserver.cpp @@ -1,6 +1,6 @@ #include "frmwebserver.h" #include "ui_frmwebserver.h" -#include "quihelper.h" +#include "qthelper.h" frmWebServer::frmWebServer(QWidget *parent) : QWidget(parent), ui(new Ui::frmWebServer) { diff --git a/tool/nettool/main.cpp b/tool/nettool/main.cpp index 96951d8..a23f0a0 100644 --- a/tool/nettool/main.cpp +++ b/tool/nettool/main.cpp @@ -1,5 +1,5 @@ #include "frmmain.h" -#include "quihelper.h" +#include "qthelper.h" int main(int argc, char *argv[]) { @@ -14,10 +14,10 @@ int main(int argc, char *argv[]) a.setWindowIcon(QIcon(":/main.ico")); //设置编码+字体+中文翻译文件 - QUIHelper::initAll(); + QtHelper::initAll(); //读取配置文件 - AppConfig::ConfigFile = QString("%1/%2.ini").arg(QUIHelper::appPath()).arg(QUIHelper::appName()); + AppConfig::ConfigFile = QString("%1/%2.ini").arg(QtHelper::appPath()).arg(QtHelper::appName()); AppConfig::readConfig(); AppData::Intervals << "1" << "10" << "20" << "50" << "100" << "200" << "300" << "500" << "1000" << "1500" << "2000" << "3000" << "5000" << "10000"; @@ -25,9 +25,9 @@ int main(int argc, char *argv[]) AppData::readDeviceData(); frmMain w; - w.setWindowTitle("网络调试助手 V2022 (QQ: 517216493 WX: feiyangqingyun)"); + w.setWindowTitle("网络调试助手 V2023 (QQ: 517216493 WX: feiyangqingyun)"); w.resize(950, 700); - QUIHelper::setFormInCenter(&w); + QtHelper::setFormInCenter(&w); w.show(); return a.exec();