【学写LibreCAD】1 LibreCAD主程序
一、源码
- 头文件:
#ifndef MAIN_H
#define MAIN_H#include<QStringList>#define STR(x) #x
#define XSTR(x) STR(x)/*** @brief handleArgs* @param argc cli argument counter from main()* @param argv cli arguments from main()* @param argClean a list of indices to be ignored* @return*/
QStringList handleArgs(int argc, char** argv, const QList<int>& argClean);/*** @brief LCReleaseLabel return a label for the current release based on LC_VERSION in src.pro* @return "Release Candidate" - if LC_VERSION contains rc;* "BETA" - if LC_VERSION contains beta* "ALPHA" - if LC_VERSION contains alpha*/
QString LCReleaseLabel();#endif
程序文件:
#include <clocale>#include <QApplication>
#include <QByteArray>
#include <QDebug>
#include <QFileInfo>
#include <QMessageBox>
#include <QPainter>
#include <QPixmap>
#include <QSettings>
#include <QSplashScreen>#include "console_dxf2pdf.h"
#include "console_dxf2png.h"
#include "lc_application.h"
#include "main.h"
#include "qc_applicationwindow.h"
#include "qg_dlginitial.h"
#include "rs_debug.h"
#include "rs_fontlist.h"
#include "rs_patternlist.h"
#include "rs_settings.h"
#include "rs_system.h"namespace{void restoreWindowGeometry(QC_ApplicationWindow& appWin, QSettings& settings);
// update splash for alpha/beta names)void updateSplash(const std::unique_ptr<QSplashScreen>& splash);
}
/*** Main. 创建应用程序窗口。*/// fixme - sand - refactor and split to several specialized functions
int main(int argc, char** argv){QT_REQUIRE_VERSION(argc, argv, "5.2.1"); //确保 LibreCAD 在 Qt 5.2.1 或更高版本上运行//检查前两个参数,以决定我们是要将librecad作为控制台dxf2pdf还是dxf2png工具运行。在Linux上,我们可以创建一个指向librecad可执行文件的链接,并将其命名为dxf2pdf。因此,我们可以运行以下任一操作://librecad dxf2pdf[选项]...//或者只是:dxf2pdf[选项]...for (int i = 0; i < qMin(argc, 2); i++) {QString arg(argv[i]);if (i == 0) {arg = QFileInfo(QFile::decodeName(argv[i])).baseName();}if (arg.compare("dxf2pdf") == 0) {return console_dxf2pdf(argc, argv);}if (arg.compare("dxf2png") == 0 || arg == "dxf2svg") {return console_dxf2png(argc, argv);}}RS_DEBUG->setLevel(RS_Debug::D_WARNING);LC_Application app(argc, argv);QCoreApplication::setOrganizationName("LibreCAD");QCoreApplication::setApplicationName("LibreCAD");QCoreApplication::setApplicationVersion(XSTR(LC_VERSION));RS_Settings::init(app.organizationName(), app.applicationName());QGuiApplication::setDesktopFileName("librecad.desktop");QSettings settings; // fixme - direct invocation of settingsbool first_load = settings.value("Startup/FirstLoad", 1).toBool();const QString lpDebugSwitch0("-d"),lpDebugSwitch1("--debug") ;const QString help0("-h"), help1("--help");bool allowOptions=true;QList<int> argClean;for (int i=0; i<argc; i++){QString argstr(argv[i]);if(allowOptions&&QString::compare("--", argstr)==0){allowOptions=false;continue;}if (allowOptions && (help0.compare(argstr, Qt::CaseInsensitive)==0 ||help1.compare(argstr, Qt::CaseInsensitive)==0 )){qDebug()<<"Usage: librecad [command] <options> <dxf file>";qDebug()<<"";qDebug()<<"Commands:";qDebug()<<"";qDebug()<<" dxf2pdf\tRun librecad as console dxf2pdf tool. Use -h for help.";qDebug()<<" dxf2png\tRun librecad as console dxf2png tool. Use -h for help.";qDebug()<<" dxf2svg\tRun librecad as console dxf2svg tool. Use -h for help.";qDebug()<<"";qDebug()<<"Options:";qDebug()<<"";qDebug()<<" -h, --help\tdisplay this message";qDebug()<<" -d, --debug <level>";qDebug()<<"";RS_DEBUG->print( RS_Debug::D_NOTHING, "possible debug levels:");RS_DEBUG->print( RS_Debug::D_NOTHING, " %d Nothing", RS_Debug::D_NOTHING);RS_DEBUG->print( RS_Debug::D_NOTHING, " %d Critical", RS_Debug::D_CRITICAL);RS_DEBUG->print( RS_Debug::D_NOTHING, " %d Error", RS_Debug::D_ERROR);RS_DEBUG->print( RS_Debug::D_NOTHING, " %d Warning", RS_Debug::D_WARNING);RS_DEBUG->print( RS_Debug::D_NOTHING, " %d Notice", RS_Debug::D_NOTICE);RS_DEBUG->print( RS_Debug::D_NOTHING, " %d Informational", RS_Debug::D_INFORMATIONAL);RS_DEBUG->print( RS_Debug::D_NOTHING, " %d Debugging", RS_Debug::D_DEBUGGING);exit(0);}if (allowOptions&& (argstr.startsWith(lpDebugSwitch0, Qt::CaseInsensitive) ||argstr.startsWith(lpDebugSwitch1, Qt::CaseInsensitive) )){argClean<<i;// to control the level of debugging output use --debug with level 0-6, e.g. --debug3// for a list of debug levels use --debug?// if no level follows, the debugging level is setargstr.remove(QRegularExpression("^"+lpDebugSwitch0));argstr.remove(QRegularExpression("^"+lpDebugSwitch1));char level;if(argstr.size()==0){if(i+1<argc){if(QRegularExpression(R"(\d*)").match(argv[i+1]).hasMatch()){++i;qDebug()<<"reading "<<argv[i]<<" as debugging level";level=argv[i][0];argClean<<i;} else {level = '3';}}else {level = '3'; //default to D_WARNING}}else {level = argstr.toStdString()[0];}switch(level){case '?' : {RS_DEBUG->print(RS_Debug::D_NOTHING, "possible debug levels:");RS_DEBUG->print(RS_Debug::D_NOTHING, " %d Nothing", RS_Debug::D_NOTHING);RS_DEBUG->print(RS_Debug::D_NOTHING, " %d Critical", RS_Debug::D_CRITICAL);RS_DEBUG->print(RS_Debug::D_NOTHING, " %d Error", RS_Debug::D_ERROR);RS_DEBUG->print(RS_Debug::D_NOTHING, " %d Warning", RS_Debug::D_WARNING);RS_DEBUG->print(RS_Debug::D_NOTHING, " %d Notice", RS_Debug::D_NOTICE);RS_DEBUG->print(RS_Debug::D_NOTHING, " %d Informational", RS_Debug::D_INFORMATIONAL);RS_DEBUG->print(RS_Debug::D_NOTHING, " %d Debugging", RS_Debug::D_DEBUGGING);return 0;}case '0' + RS_Debug::D_NOTHING : {RS_DEBUG->setLevel(RS_Debug::D_NOTHING);break;}case '0' + RS_Debug::D_CRITICAL : {RS_DEBUG->setLevel(RS_Debug::D_CRITICAL);break;}case '0' + RS_Debug::D_ERROR : {RS_DEBUG->setLevel(RS_Debug::D_ERROR);break;}case '0' + RS_Debug::D_WARNING : {RS_DEBUG->setLevel(RS_Debug::D_WARNING);break;}case '0' + RS_Debug::D_NOTICE : {RS_DEBUG->setLevel(RS_Debug::D_NOTICE);break;}case '0' + RS_Debug::D_INFORMATIONAL : {RS_DEBUG->setLevel(RS_Debug::D_INFORMATIONAL);break;}case '0' + RS_Debug::D_DEBUGGING : {RS_DEBUG->setLevel(RS_Debug::D_DEBUGGING);break;}default : {RS_DEBUG->setLevel(RS_Debug::D_DEBUGGING);break;}}}}RS_DEBUG->print("param 0: %s", argv[0]);QFileInfo prgInfo( QFile::decodeName(argv[0]) );QString prgDir(prgInfo.absolutePath());RS_SYSTEM->init(app.applicationName(), app.applicationVersion(), XSTR(QC_APPDIR), prgDir);// parse command line arguments that might not need a launched program:QStringList fileList = handleArgs(argc, argv, argClean);QString unit = settings.value("Defaults/Unit", "Invalid").toString();// show initial config dialog:if (first_load){RS_DEBUG->print("main: show initial config dialog..");QG_DlgInitial di(nullptr);QPixmap pxm(":/main/intro_librecad.png");di.setPixmap(pxm);if (di.exec()) {unit = LC_GET_ONE_STR("Defaults", "Unit", "None");}RS_DEBUG->print("main: show initial config dialog: OK");}auto splash = std::make_unique<QSplashScreen>();bool show_splash = settings.value("Startup/ShowSplash", 1).toBool();if (show_splash){updateSplash(splash);app.processEvents();RS_DEBUG->print("main: splashscreen: OK");}RS_DEBUG->print("main: init fontlist..");RS_FONTLIST->init();RS_DEBUG->print("main: init fontlist: OK");RS_DEBUG->print("main: init patternlist..");RS_PATTERNLIST->init();RS_DEBUG->print("main: init patternlist: OK");RS_DEBUG->print("main: loading translation..");settings.beginGroup("Appearance");QString lang = settings.value("Language", "en").toString();QString langCmd = settings.value("LanguageCmd", "en").toString();settings.endGroup();RS_SYSTEM->loadTranslation(lang, langCmd);RS_DEBUG->print("main: loading translation: OK");RS_DEBUG->print("main: creating main window..");QC_ApplicationWindow& appWin = *QC_ApplicationWindow::getAppWindow();
#ifdef Q_OS_MACapp.installEventFilter(&appWin);
#endifRS_DEBUG->print("main: setting caption");appWin.setWindowTitle(app.applicationName());RS_DEBUG->print("main: show main window");settings.beginGroup("Defaults");if( !settings.contains("UseQtFileOpenDialog")) {
#ifdef Q_OS_LINUX// on Linux don't use native file dialog// because of case insensitive filters (issue #791)settings.setValue("UseQtFileOpenDialog", QVariant(1));
#elsesettings.setValue("UseQtFileOpenDialog", QVariant(0));
#endif}settings.endGroup();if (!first_load) {restoreWindowGeometry(appWin, settings);}bool maximize = settings.value("Startup/Maximize", 0).toBool();if (maximize || first_load) {appWin.showMaximized();}else {appWin.show();}RS_DEBUG->print("main: set focus");appWin.setFocus();RS_DEBUG->print("main: creating main window: OK");if (show_splash){RS_DEBUG->print("main: updating splash");splash->raise();splash->showMessage(QObject::tr("Loading..."),Qt::AlignRight|Qt::AlignBottom, Qt::black);RS_DEBUG->print("main: processing events");qApp->processEvents();RS_DEBUG->print("main: updating splash: OK");}// Set LC_NUMERIC so that entering numeric values uses . as the decimal separatorsetlocale(LC_NUMERIC, "C");RS_DEBUG->print("main: loading files..");
#ifdef Q_OS_MAC// get the file list from LC_ApplicationfileList << app.fileList();
#endif// reopen files that we open during last close of application// we'll reopen them if no explicit files to open are provided in command linebool reopenLastFiles;QString lastFiles;QString activeFile;LC_GROUP("Startup");{reopenLastFiles = LC_GET_BOOL("OpenLastOpenedFiles");lastFiles = LC_GET_STR("LastOpenFilesList", "");activeFile = LC_GET_STR("LastOpenFilesActive", "");bool checkForNewVersion = LC_GET_BOOL("CheckForNewVersions", true);if (reopenLastFiles && fileList.isEmpty() && !lastFiles.isEmpty()) {foreach(const QString &filename, lastFiles.split(";")) {if (!filename.isEmpty() && QFileInfo::exists(filename))fileList << filename;}}bool files_loaded = false;for (QStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it) {if (show_splash) {splash->showMessage(QObject::tr("Loading File %1..").arg(QDir::toNativeSeparators(*it)),Qt::AlignRight | Qt::AlignBottom, Qt::black);qApp->processEvents();}appWin.slotFileOpen(*it);files_loaded = true;}if (reopenLastFiles) {appWin.activateWindowWithFile(activeFile);}RS_DEBUG->print("main: loading files: OK");if (!files_loaded) {appWin.slotFileNewNew();}if (show_splash) {splash->finish(&appWin);splash.release();}if (checkForNewVersion) {appWin.checkForNewVersion();}}LC_GROUP_END();if (first_load)settings.setValue("Startup/FirstLoad", 0);RS_DEBUG->print("main: entering Qt event loop");QCoreApplication::processEvents();int return_code = app.exec();RS_DEBUG->print("main: exited Qt event loop");// Destroy the singletonQC_ApplicationWindow::getAppWindow().reset();return return_code;
}/*** Handles command line arguments that might not require a GUI.** @return list of files to load on startup.*/
QStringList handleArgs(int argc, char** argv, const QList<int>& argClean){RS_DEBUG->print("main: handling args..");QStringList ret;bool doexit = false;for (int i=1; i<argc; i++) {if(argClean.indexOf(i)>=0) continue;if (!QString(argv[i]).startsWith("-")){QString fname = QDir::toNativeSeparators(QFileInfo(QFile::decodeName(argv[i])).absoluteFilePath());ret.append(fname);}else if (QString(argv[i])=="--exit"){doexit = true;}}if (doexit) {exit(0);}RS_DEBUG->print("main: handling args: OK");return ret;
}QString LCReleaseLabel(){QString version{XSTR(LC_VERSION)};QString label;const std::map<QString, QString> labelMap = {{"rc", QObject::tr("Release Candidate")},{"beta", QObject::tr("BETA")},{"alpha", QObject::tr("ALPHA")}};for (const auto& [key, value]: labelMap) {if (version.contains(key, Qt::CaseInsensitive)) {label=value;break;}}return label;
}namespace {void restoreWindowGeometry(QC_ApplicationWindow& appWin, QSettings& settings){settings.beginGroup("Geometry");auto geometryB64 = settings.value("/WindowGeometry").toString().toUtf8();auto geometry = QByteArray::fromBase64(geometryB64, QByteArray::Base64Encoding);if (!geometry.isEmpty()) {appWin.restoreGeometry(geometry);} else {// fallbackint windowWidth = settings.value("WindowWidth", 1024).toInt();int windowHeight = settings.value("WindowHeight", 1024).toInt();int windowX = settings.value("WindowX", 32).toInt();int windowY = settings.value("WindowY", 32).toInt();appWin.resize(windowWidth, windowHeight);appWin.move(windowX, windowY);}settings.endGroup();}// Update Splash image to show "ALPHA", "BETA", and "Release Candidate"
QPixmap getSplashImage(const std::unique_ptr<QSplashScreen>& splash, const QString& label);
// Update Splash Screenvoid updateSplash(const std::unique_ptr<QSplashScreen>& splash){if (splash == nullptr)return;QString label = LCReleaseLabel();if (label.isEmpty())return;QPixmap splashImage = getSplashImage(splash, label);splash->setPixmap(splashImage);splash->setAttribute(Qt::WA_DeleteOnClose);splash->show();splash->showMessage(QObject::tr("Loading.."),Qt::AlignRight|Qt::AlignBottom, Qt::black);}// Update Splash image to show "ALPHA", "BETA", and "Release Candidate"QPixmap getSplashImage(const std::unique_ptr<QSplashScreen>& splash, const QString& label){if (splash == nullptr)return {};QPixmap pixmapSplash(":/main/splash_librecad.png");QPainter painter(&pixmapSplash);const double factorX = pixmapSplash.width()/542.;const double factorY = pixmapSplash.height()/337.;painter.setPen(QColor(255, 0, 0, 128));QRectF labelRect{QPointF{280.*factorX, 130.*factorY}, QPointF{480.*factorX, 170.*factorY}};QFont font;font.setPixelSize(int(labelRect.height()) - 2);painter.setFont(font);painter.drawText(labelRect,Qt::AlignRight, label);return pixmapSplash;}
}
二、代码介绍
- Qt 版本检查
QT_REQUIRE_VERSION(argc, argv, "5.2.1");
确保应用程序运行在 Qt 5.2.1 或更高版本上。
- 控制台模式检测
for (int i = 0; i < qMin(argc, 2); i++) {// 检查是否为 dxf2pdf/dxf2png 命令if (arg.compare("dxf2pdf") == 0) return console_dxf2pdf(...);if (arg.compare("dxf2png") == 0) return console_dxf2png(...);
}
检测是否以命令行工具模式运行,用于文件格式转换(如 PDF/PNG/SVG)。
- 应用程序初始化
LC_Application app(argc, argv);
QCoreApplication::setOrganizationName("LibreCAD");
// ... 其他应用程序设置 ...
RS_Settings::init(...);
-
创建 Qt 应用程序对象。
-
设置组织和应用程序的元数据。
-
初始化持久化设置系统。
- 命令行参数处理
QStringList fileList = handleArgs(argc, argv, argClean);
处理以下参数:
- 调试级别控制(-d/–debug)。
- 帮助信息输出(-h/–help)。
- 要打开的文件路径。
- 特殊命令(如 --exit)。
- 首次运行配置
if (first_load) {QG_DlgInitial di(nullptr);// 显示初始配置对话框
}
- 如果是第一次运行,显示初始设置对话框。
- 设置默认单位和其他基本偏好。
- 启动画面设置
auto splash = std::make_unique<QSplashScreen>();
updateSplash(splash); // 添加版本标签(如 ALPHA/BETA 等)
- 创建并自定义启动画面。
- 使用 getSplashImage() 添加版本标签。
- 资源初始化
RS_FONTLIST->init(); // 字体
RS_PATTERNLIST->init(); // 图案
RS_SYSTEM->loadTranslation(...); // 本地化
- 加载 CAD 所需的资源。
- 设置多语言支持。
- 主窗口创建
QC_ApplicationWindow& appWin = *QC_ApplicationWindow::getAppWindow();
restoreWindowGeometry(appWin, settings);
- 使用单例模式创建主应用程序窗口。
- 从设置中恢复窗口的几何状态。
- 文件处理
// 如果配置了,重新打开上次的文件
if (reopenLastFiles) fileList = lastFiles.split(";"); // 加载命令行指定的文件
for (QString file : fileList) appWin.slotFileOpen(file);
- 处理命令行指定的文件以及“重新打开上次文件”的功能。
- 如果没有指定文件,则创建新文档。
- 事件循环与清理
int return_code = app.exec();
// ... 清理 ...
return return_code;
- 启动 Qt 事件循环。
- 在退出时进行适当的清理。
- 在关闭时保存设置。
关键架构特性
- 单例模式:用于主应用程序窗口(QC_ApplicationWindow::getAppWindow())。
- 工厂模式:用于字体和图案资源的初始化。
- 命令分发:同时支持 GUI 和命令行模式。
- 持久化:使用 QSettings 保存窗口几何状态和偏好设置。
- 国际化:通过翻译文件支持多语言。
重要的辅助函数
- handleArgs():处理命令行参数。
- restoreWindowGeometry():从设置中恢复窗口状态。
- updateSplash():自定义启动画面,添加版本信息。
- LCReleaseLabel():确定版本类型(如 Alpha/Beta 等)。
总结
这段代码展示了一个成熟的 Qt 应用程序结构,具有清晰的职责分离:
- 初始化:应用程序和资源的初始化。
- 资源管理:字体、图案和本地化资源的加载。
- UI 设置:主窗口和启动画面的创建与配置。
- 命令行处理:支持命令行模式和文件加载。
通过良好的架构设计和模块化实现,LibreCAD 的主程序能够高效地处理多种运行场景,并为用户提供一致的使用体验。
相关文章:
【学写LibreCAD】1 LibreCAD主程序
一、源码 头文件: #ifndef MAIN_H #define MAIN_H#include<QStringList>#define STR(x) #x #define XSTR(x) STR(x)/*** brief handleArgs* param argc cli argument counter from main()* param argv cli arguments from main()* param argClean a list…...

Android Studio超级详细讲解下载、安装配置教程(建议收藏)
博主介绍:✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉着互联网精神开源贡献精神,答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有…...
CDN与群联云防护的技术差异在哪?
CDN(内容分发网络)与群联云防护是两种常用于提升网站性能和安全的解决方案,但两者的核心目标和技术实现存在显著差异。本文将从防御机制、技术架构、适用场景和代码实现等方面详细对比两者的区别,并提供可直接运行的代码示例。 一…...

故障诊断 | Matlab实现基于DBO-BP-Bagging多特征分类预测/故障诊断
故障诊断 | Matlab实现基于DBO-BP-Bagging多特征分类预测/故障诊断 目录 故障诊断 | Matlab实现基于DBO-BP-Bagging多特征分类预测/故障诊断分类效果基本介绍模型描述DBO-BP-Bagging蜣螂算法优化多特征分类预测一、引言1.1、研究背景和意义1.2、研究现状1.3、研究目的与方法 二…...

Linux-SaltStack配置
文章目录 SaltStack配置 🏡作者主页:点击! 🤖Linux专栏:点击! ⏰️创作时间:2025年02月24日20点51分 SaltStack配置 SaltStack 中既支持SSH协议也支持我们的一个客户端 #获取公钥(…...

内网渗透测试-Vulnerable Docker靶场
靶场来源: Vulnerable Docker: 1 ~ VulnHub 描述:Down By The Docker 有没有想过在容器中玩 docker 错误配置、权限提升等? 下载此 VM,拿出您的渗透测试帽并开始使用 我们有 2 种模式: - HARD:这需要您将 d…...
云计算如何解决延迟问题?
在云计算中,延迟(latency)指的是从请求发出到收到响应之间的时间间隔。延迟过高可能会严重影响用户体验,特别是在需要实时响应的应用中,如在线游戏、视频流、金融交易等。云计算服务如何解决延迟问题,通常依…...

飞书webhook监控业务系统端口
钉钉告警没有额度了,替代方案使用企业微信或者是飞书,以下脚本是飞书为例 监控ping也就是活动主机 #!/bin/bash # IP Ping 监控脚本 date$(date "%Y-%m-%d %H:%M:%S") # 根据实际情况修改飞书 Webhook 地址 webhook"https://open.feish…...

电脑键盘知识
1、键盘四大功能区 1. 功能区 2. 主要信息输入区 3. 编辑区 4. 数字键盘区 笔记本电脑键盘的功能区,使用前需先按Fn键 1.1、功能区 ESC:退出 F1:显示帮助信息 F2:重命名 F4:重复上一步操作 F5:刷新网页 …...
Oracle23版本 创建用户 报 00959和65096错误解决办法
00959错误解决办法,用户名必须已 c##或者C##开头 65096错误解决办法,创建用户名时去掉DEFAULT TABLESPACE smallrainTablespace这个属性 附上oracle 23版本创建表空间和用户语句; sqlplus sys as sysdba CREATE TABLESPACE smallrainOrac…...

SAP-ABAP:使用ST05(SQL Trace)追踪结构字段来源的步骤
ST05 是 SAP 提供的 SQL 跟踪工具,可以记录程序运行期间所有数据库操作(如 SELECT、UPDATE、INSERT)。通过分析跟踪结果,可以精准定位程序中结构字段对应的数据库表。 步骤1:激活ST05跟踪 事务码 ST05 → 点击 Activa…...

《深度学习实战》第3集:循环神经网络(RNN)与序列建模
第3集:循环神经网络(RNN)与序列建模 引言 在深度学习领域,处理序列数据(如文本、语音、时间序列等)是一个重要的研究方向。传统的全连接网络和卷积神经网络(CNN)难以直接捕捉序列中…...

winfrom的progressBar 鼠标移上去显示 进度条的时间
需求描述: 播放IPC摄像头(海康、大华)的录像回放,视频窗口下方有个进度条,能显示当前录像播放的进度,点击进度条能将视频跳转到指定的时间点继续播放... 现在需要再进度条上显示视频的时间,用来…...

如何在WordPress网站中查看移动版本—快速预览与自定义设置
在WordPress网站的构建过程中,确保网站在移动端的显示效果至关重要。毕竟,随着越来越多的用户通过手机访问互联网,一个优化良好的移动版网站将直接影响用户的留存率和访问体验。 如果你是WordPress网站的所有者,本文将向你介绍如…...
wordpress按分类ID调用最新、推荐、随机内容
在WordPress中,可以通过自定义查询(WP_Query)来按分类ID调用最新、推荐(自定义字段或标签)、随机内容。以下是一些示例代码,帮助你实现这些功能。 1. 按分类ID调用最新内容 以下代码可以调用指定分类ID下的最新文章: <?php // 设置分类…...

excel单、双字节字符转换函数(中英文输入法符号转换)
在Excel中通常使用函数WIDECHAR和ASC来实现单、双字节字符之间的转换。其中 WIDECHAR函数将所有的字符转换为双字节,ASC函数将所有的字符转换为单字节 首先来解释一下单双字节的含义。单字节一般对应英文输入法的输入,如英文字母,英文输入法…...

能不能用Ai来开发出一款APP?很早就想过能不能用Ai来开发出一款APP?
现在AI这么流行,长青很早就想过能不能用Ai来开发出一款APP? 然后从1月份开始长青就开始着手用AI写一款音乐app,参考了落雪音乐的开发技术栈,长青这里也准备用ReactNative去写。 首先声明一点,长青本身不会开发app的&a…...

lattice hdl实现spi接口
在lattice工具链中实现SPI接口通常涉及以下步骤: 定义硬件SPI接口的管脚。配置SPI时钟和模式。编写SPI主机或从机的控制逻辑。 展示了如何在Lattice工具链中使用HDL语言(例如Verilog)来配置SPI接口: lattice工程 顶层:spi_slave_top.v `timescale 1ns/ 1ps module spi_…...

超过DeepSeek、o3,Claude发布全球首个混合推理模型,并将完成新一轮35亿美元融资...
Anthropic于2025年2月25日发布全球首个“混合推理”AI模型Claude 3.7 Sonnet,并在融资层面取得重大进展,计划完成35亿美元的新一轮融资,估值将达615亿美元。以下是核心信息整理: 技术突破:双思维模型与代码能力 1. 混合…...

AI如何通过大数据分析提升制造效率和决策智能化
人工智能(AI)与大数据技术的融合,不仅重新定义了生产流程,更让企业实现了从“经验驱动”到“数据智能驱动”的跨越式升级。 从“模糊经验”到“精准洞察” 传统制造业依赖人工经验制定生产计划,但面对复杂多变的市…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...