Sandboxie-沙箱软件-Plus版本(Qt)-主框架程序-SandMan.exe-创建语言文件-tr-Qt-语言国际化

news2024/9/25 15:28:42

文章目录

    • 1.功能介绍
    • 2.Qt语言国际化
    • 3.设置软件的语言版本
    • 4.作者答疑

1.功能介绍

沙箱软件的增强版本采用Qt架构开发,核心模块与经典版本相同,本文主要介绍SandMan.exe这个主程序代码。在main.cpp这个入口函数里,有主窗口入口,如下所示:

int main(int argc, char *argv[])
{
......省略一部分初始化代码

	CSandMan* pWnd = new CSandMan();

	QObject::connect(&app, SIGNAL(messageReceived(const QString&)), pWnd, SLOT(OnMessage(const QString&)));

	int ret =  app.exec();

	delete pWnd;

	delete theConf;
	theConf = NULL;

	return ret;
}

CSandMan这个类继承至QMainWindow,是Qt典型的主窗口。查看主窗口函数的构造函数:

CSandMan::CSandMan(QWidget *parent)
	: QMainWindow(parent)
{
#if defined(Q_OS_WIN)
	MainWndHandle = (HWND)QWidget::winId();

	QApplication::instance()->installNativeEventFilter(new CNativeEventFilter);
#endif

	CArchive::Init();

	theGUI = this;

	m_DarkTheme = false;
	m_FusionTheme = false;

	QDesktopServices::setUrlHandler("http", this, "OpenUrl");
	QDesktopServices::setUrlHandler("https", this, "OpenUrl");
	QDesktopServices::setUrlHandler("sbie", this, "OpenUrl");

	m_StartMenuUpdatePending = false;

	m_ThemeUpdatePending = false;
	m_DefaultStyle = QApplication::style()->objectName();
	m_DefaultPalett = QApplication::palette();
	m_DefaultFontSize = QApplication::font().pointSizeF();

	m_DarkPalett.setColor(QPalette::Light, QColor(96, 96, 96));
	m_DarkPalett.setColor(QPalette::Midlight, QColor(64, 64, 64));
	m_DarkPalett.setColor(QPalette::Mid, QColor(48, 48, 48));
	m_DarkPalett.setColor(QPalette::Dark, QColor(53, 53, 53));
	m_DarkPalett.setColor(QPalette::Shadow, QColor(25, 25, 25));
	m_DarkPalett.setColor(QPalette::Window, QColor(53, 53, 53));
	m_DarkPalett.setColor(QPalette::WindowText, Qt::white);
	m_DarkPalett.setColor(QPalette::Base, QColor(25, 25, 25));
	m_DarkPalett.setColor(QPalette::AlternateBase, QColor(53, 53, 53));
	m_DarkPalett.setColor(QPalette::ToolTipBase, Qt::lightGray);
	m_DarkPalett.setColor(QPalette::ToolTipText, Qt::white);
	m_DarkPalett.setColor(QPalette::Text, Qt::white);
	m_DarkPalett.setColor(QPalette::Button, QColor(53, 53, 53));
	m_DarkPalett.setColor(QPalette::ButtonText, Qt::white);
	m_DarkPalett.setColor(QPalette::BrightText, Qt::red);
	m_DarkPalett.setColor(QPalette::Link, QColor(218, 130, 42));
	m_DarkPalett.setColor(QPalette::LinkVisited, QColor(218, 130, 42));
	m_DarkPalett.setColor(QPalette::Highlight, QColor(42, 130, 218));
	m_DarkPalett.setColor(QPalette::HighlightedText, Qt::black);
	m_DarkPalett.setColor(QPalette::PlaceholderText, QColor(96, 96, 96));
	m_DarkPalett.setColor(QPalette::Disabled, QPalette::WindowText, Qt::darkGray);
	m_DarkPalett.setColor(QPalette::Disabled, QPalette::Text, Qt::darkGray);
	m_DarkPalett.setColor(QPalette::Disabled, QPalette::Light, Qt::black);
	m_DarkPalett.setColor(QPalette::Disabled, QPalette::ButtonText, Qt::darkGray);

	LoadLanguage();

	if (!theConf->IsWritable()) {
		QMessageBox::critical(this, "Sandboxie-Plus", tr("WARNING: Sandboxie-Plus.ini in %1 cannot be written to, settings will not be saved.").arg(theConf->GetConfigDir()));
	}

	m_bExit = false;

	theAPI = new CSbiePlusAPI(this);
	connect(theAPI, SIGNAL(StatusChanged()), this, SLOT(OnStatusChanged()));
	connect(theAPI, SIGNAL(BoxAdded(const CSandBoxPtr&)), this, SLOT(OnBoxAdded(const CSandBoxPtr&)));
	connect(theAPI, SIGNAL(BoxClosed(const CSandBoxPtr&)), this, SLOT(OnBoxClosed(const CSandBoxPtr&)));
	connect(theAPI, SIGNAL(BoxCleaned(CSandBoxPlus*)), this, SLOT(OnBoxCleaned(CSandBoxPlus*)));

	QString appTitle = tr("Sandboxie-Plus v%1").arg(GetVersion());
	this->setWindowTitle(appTitle);
	setAcceptDrops(true);

	m_pBoxBorder = new CBoxBorder(theAPI, this);
	m_SbieTemplates = new CSbieTemplates(theAPI, this);

	m_bConnectPending = false;
	m_bStopPending = false;

	m_pUpdater = new COnlineUpdater(this);
	m_pMainWidget = new QWidget(this);
	m_pMenuBar = menuBar();
	connect(m_pMenuBar, SIGNAL(hovered(QAction*)), this, SLOT(OnMenuHover(QAction*)));

	QWidget* pMenuWidget = new QWidget(this);
	m_pMenuLayout = new QHBoxLayout(pMenuWidget);
	m_pMenuLayout->setContentsMargins(0, 0, 0, 0);
	//m_pMenuLayout->addWidget(m_pMenuBar);
	m_pMenuLayout->setMenuBar(m_pMenuBar);
	//m_pMenuLayout->addWidget(m_pLabel);
	//m_pMenuLayout->addStretch(10);
	setMenuWidget(pMenuWidget);

	CreateUI();
	setCentralWidget(m_pMainWidget);

	m_pTraceInfo = new QLabel();
	m_pDisabledForce = new QLabel();
	m_pDisabledRecovery = new QLabel();
	m_pDisabledMessages = new QLabel();
	statusBar()->addPermanentWidget(m_pTraceInfo);
	statusBar()->addPermanentWidget(m_pDisabledForce);
	statusBar()->addPermanentWidget(m_pDisabledRecovery);
	statusBar()->addPermanentWidget(m_pDisabledMessages);
	OnDisablePopUp(); // update statusbar

	m_pHotkeyManager = new UGlobalHotkeys(this);
	connect(m_pHotkeyManager, SIGNAL(activated(size_t)), SLOT(OnHotKey(size_t)));
	SetupHotKeys();

	m_BoxColors[CSandBoxPlus::eHardenedPlus] = qRgb(238,35,4);
	m_BoxColors[CSandBoxPlus::eHardened] = qRgb(247,125,2);
	m_BoxColors[CSandBoxPlus::eDefaultPlus] = qRgb(1,133,248);
	m_BoxColors[CSandBoxPlus::eDefault] = qRgb(246,246,2);
	m_BoxColors[CSandBoxPlus::eAppBoxPlus] = qRgb(3,232,232);
	m_BoxColors[CSandBoxPlus::eAppBox] = qRgb(0,253,0);
	m_BoxColors[CSandBoxPlus::eInsecure] = qRgb(244,3,244);
	m_BoxColors[CSandBoxPlus::eOpen] = qRgb(255,255,255);

	CreateTrayIcon();
	LoadState();
	m_pProgressDialog = new CProgressDialog("");
	m_pProgressDialog->setWindowModality(Qt::ApplicationModal);
	connect(m_pProgressDialog, SIGNAL(Cancel()), this, SLOT(OnCancelAsync()));
	m_pProgressModal = false;
	m_pPopUpWindow = new CPopUpWindow();
	bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false);
	this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
	m_pPopUpWindow->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
	m_pProgressDialog->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);

	//connect(theAPI, SIGNAL(LogMessage(const QString&, bool)), this, SLOT(OnLogMessage(const QString&, bool)));
	connect(theAPI, SIGNAL(LogSbieMessage(quint32, const QStringList&, quint32)), this, SLOT(OnLogSbieMessage(quint32, const QStringList&, quint32)));
	connect(theAPI, SIGNAL(NotAuthorized(bool, bool&)), this, SLOT(OnNotAuthorized(bool, bool&)), Qt::DirectConnection);
	connect(theAPI, SIGNAL(QueuedRequest(quint32, quint32, quint32, const QVariantMap&)), this, SLOT(OnQueuedRequest(quint32, quint32, quint32, const QVariantMap&)), Qt::QueuedConnection);
	connect(theAPI, SIGNAL(FileToRecover(const QString&, const QString&, const QString&, quint32)), this, SLOT(OnFileToRecover(const QString&, const QString&, const QString&, quint32)), Qt::QueuedConnection);
	connect(theAPI, SIGNAL(ConfigReloaded()), this, SLOT(OnIniReloaded()));

    connect(qApp, &QGuiApplication::commitDataRequest, this, &CSandMan::commitData);

	m_uTimerID = startTimer(1000);

	bool bAutoRun = QApplication::arguments().contains("-autorun");
	if (!bAutoRun && g_PendingMessage.isEmpty())
		SafeShow(this);

	OnStatusChanged();
	if (CSbieUtils::IsRunning(CSbieUtils::eAll) || theConf->GetBool("Options/StartIfStopped", true))
	{
		SB_RESULT(void*) Status = ConnectSbie();
		HandleMaintenance(Status);
	}
	//qApp->setWindowIcon(GetIcon("IconEmptyDC", false));
}

主窗口不是采用.ui文件生成的,它是由代码动态生成的。主要处理了界面语言问题,界面信号槽问题,界面UI搭配问题,下面重点就这几个问题,进行分析。

2.Qt语言国际化

qt提供了一个翻译机制,只要是代码中用tr()包含起来的文本,程序可以额外提供一个翻译文件(*.ts),有了这个翻译文件可以将tr()中包含的文本人为翻译为任何语言,这样对于不同语言的使用者,只需要选择自己使用的语言,程序界面就会自动完成语言转换。
在这里插入图片描述
先创建工程文件,然后编辑.pri文件,在末尾加入:

TRANSLATIONS += yourproject_zh.ts

然后采用工具生成ts文件,注意采用对应VS对台的控制台,命令如下:

"D:\QT\vs2019Qt\Qt5_15_2_VS2019_Static_64\bin\lupdate.exe" –verbose QtConnect.pri

目录之下生成了对应的ts文件,然后使用工具linguist.exe编辑ts文件,如下所示:
在这里插入图片描述
可以设置不同语言的版本。
在这里插入图片描述
在这里插入图片描述
在下面输入对应的中文翻译。
然后采用lrelease.exe工具转成二进制文件,如下所示:

"D:\QT\vs2019Qt\Qt5_15_2_VS2019_Static_64\bin\lrelease.exe" –verbose QtConnect.pri

3.设置软件的语言版本

有2种方法设置软件的语言版:
①在项目启动时设置界面语言
②在项目启动过程中动态切换语言

#include <QTranslator>
#include <QSettings>
QTranslator *trans=NULL;
QString readSetting();

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    trans=new QTranslator;
    QString curLang=readSetting();//从注册表读取上次的语言版本
    if(curLang=="EN") //若为“EN”,就调用lang_en.qm翻译文件
        trans->load("lang_en.qm");
    else//否则就调用lang_cn.qm翻译文件
        trans->load("lang_cn.qm");
    a.installTranslator(trans);//给应用程序安装翻译器,实现需要的界面版本
    
    MainWindow w;
    w.show();

    return a.exec();
}

//用于从注册表里读取上次设置的界面语言版本
QString readSetting()
{
    QString organization="WWB-Qt";
    QString appName="samp6_22";
    QSettings settings(organization,appName);
    QString Language=settings.value("Language","EN").toString();
    return Language;
}

在软件运行时可以动态切换语言,无需重启软件就可以切换语言界面

#include <QTranslator>
#include <QSettings>

class MainWindow : public QMainWindow
{
private:
    QTranslator *trans=NULL;

};

“中文版”按钮的响应函数

void MainWindow::on_actLang_CN_triggered()
{
    qApp->removeTranslator(trans);
    delete trans;
    trans=new QTranslator;
    trans->load("lang_cn.qm");

    qApp->installTranslator(trans);
    ui->retranslateUi(this);
    QSettings settings("WWB-Q","samp6_22");
    settings.setValue("Language","CN");
}

“英文版”按钮的响应函数

void MainWindow::on_actLang_EN_triggered()
{
    qApp->removeTranslator(trans);
    delete trans;
    trans=new QTranslator;
    trans->load("lang_en.qm");

    qApp->installTranslator(trans);
    ui->retranslateUi(this);
    QSettings settings("WWB-Q","samp6_22");
    settings.setValue("Language","EN");
}

代码解释:
因为main()函数已经加载了一个翻译器,所以需要先移除当前的翻译器,才能重新创建新的翻译器,加载翻译文件,并为应用程序重新加载新翻译器。完成后调用UI的retranslateUi函数来刷新界面。retranslateUi函数时窗口的“ui_”头文件自动生成的,这个函数使用QApplication::translate()函数将所有的界面字符串进行翻译,才可以立即更新界面语言。

4.作者答疑

如有疑问,敬请留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/354706.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2.5|iot冯|方元-嵌入式linux系统开发入门|2.13+2.18

一、 Linux 指令操作题&#xff08;共5题&#xff08;共 20 分&#xff0c;每小题 4分&#xff09;与系统工作、系统状态、工作目录、文件、目录、打包压缩与搜索等主题相关。1.文件1.1文件属性1.2文件类型属性字段的第1个字符表示文件类型&#xff0c;后9个字符中&#xff0c;…

【物联网】智慧农业病虫害精准辨识竞赛思路及代码分享

来源&#xff1a;投稿 作者&#xff1a;LSC 编辑&#xff1a;学姐 比赛官网: https://www.dataglobal.cn/cmpt/signUpInfo200.html 任务描述 请参赛者设计智慧农业病虫害检测系统&#xff0c;给出一体化问题解决方案&#xff0c;鼓励参赛选手结合某一果园/农作物实际情况建立…

使用 URLSearchParams 解析和管理URL query参数

介绍 首先 URLSearchParams是一个构造函数&#xff0c;会生成一个URLSearchParams对象&#xff0c;参数类型&#xff1a; 不传 &#xff5c; string &#xff5c; object &#xff5c; URLSearchParams&#xff0c; 并且遇到特殊字符它会自动帮我们encode 和 decode const ur…

Java模块化概述

3 模块化 3.1 模块化概述 Java语言随着这些年的发展已经成为了一]影响深远的编程语言&#xff0c;无数平台,系统都采用Java语言编写。但是&#xff0c;伴随着发展&#xff0c;Java也越来越庞大&#xff0c;逐渐发展成为-门“臃肿” 的语言。而且&#xff0c;无论是运行个大型的…

Vulnhub 渗透练习(五)—— lazysysadmin1

环境搭建 下载链接 vmware 打开靶机&#xff0c;nat 网络适配&#xff0c;攻击机同样。 信息收集 一个一个的看过去&#xff0c;这边就不贴图了。 漏洞挖掘 用 kail 的 wpscan 扫一下 wordpress&#xff0c;没发现漏洞。 ┌──(geng㉿geng)-[~] └─$ wpscan --url http…

【Linux06-基础IO】4.5万字的基础IO讲解

前言 本期分享基础IO的知识&#xff0c;主要有&#xff1a; 复习C语言文件操作文件相关的系统调用文件描述符fd理解Linux下一切皆文件缓冲区文件系统软硬链接动静态库的理解和制作动静态编译 博主水平有限&#xff0c;不足之处望请斧正&#xff01; C语言文件操作 #再谈文件…

SQLSERVER2019安装步骤过程

第一步官网下载SQLSERVER软件包 目前官网只能下载最新版本2022版本。 通过迅雷下载网址 SQL Server 2019 Enterprise (x64) - DVD (Chinese-Simplified)企业版 ed2k://|file|cn_sql_server_2019_enterprise_x64_dvd_2bfe815a.iso|1632086016|58C258FF0F1D006DD3C1F5F17AF3E…

ELK_Elasticsearch环境搭建

目录 一、Windows安装elasticsearch 1、安装JDK 2、下载和解压 3、配置文件 4、启动 5、检查ES是否启动成功 6、浏览器访问 二、 Windows安装Kibana 一、Windows安装elasticsearch 1、安装JDK 安装JDK&#xff0c;至少1.8.0_73以上版本&#xff0c;验证&#xff1a;j…

dbForge Source Control for SQL Server 2.5.X Crack

SQL Server功能概述 的 dbForge 源代码管理 dbForge Source Control for SQL Server 是一个可视化的 SSMS 插件&#xff0c;具有简单易用的界面&#xff0c;可帮助您轻松跟踪 SQL Server 数据库对象中的更改内容、更改时间和原因。该工具使您能够将数据库连接到多个版本控制系统…

【Python学习笔记】40.Python3 SMTP发送邮件

前言 SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则&#xff0c;由它来控制信件的中转方式。 Python3 SMTP发送邮件 python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了…

CSS基础选择器,你认识多少?

前言在上一文初识CSS中&#xff0c;我们了解到了其格式&#xff1a;选择器{ }在初步尝试使用时&#xff0c;我们笼统的直接输入了p { }以选择p标签来对其操作&#xff0c;而这一章节里&#xff0c;我们再进一步探索有关基础选择器的相关内容&#xff0c;理解选择器的作用。选择…

2019蓝桥杯真题平方序列(填空题) C语言/C++

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小明想找到两个正整数 X 和 Y&#xff0c;满足2019<X<Y;2019^2, X^2, Y^2组成等差数列。 请你求出在所有可能的解中&#xff0c;XY 的最小值是多少&#xff1f…

QT(17)- QNetworkAccessManager

QT&#xff08;17&#xff09;- QNetworkAccessManager1 简介2 公有类型3 函数3.1 addStrictTransportSecurityHosts3.2 autoDeleteReplies3.3 cache3.4 clearAccessCache3.5 clearConnectionCache3.6 connectToHost3.7 connectToHostEncrypted3.8 cookieJar3.9 deleteResource…

Metasploit框架基础(一)

文章目录前言一、基础认知二、批量POC/EXP的构想三、poc检测框架的简单实现四、xray五、Meatsploit框架参考前言 Metasploit 一款渗透测试框架漏洞利用的集合与构建和定制满足你的需求的基础漏洞利用和验证的工具 这几个说法都是百度或者官方文档中出现的手法&#xff0c;说…

ASEMI代理FGH60N60SFD,安森美FGH60N60SFD原装IGBT

编辑-Z 安森美FGH60N60SFD原装IGBT参数&#xff1a; 型号&#xff1a;FGH60N60SFD 集电极到发射极电压&#xff08;VCES&#xff09;&#xff1a;600V 栅极到发射极电压&#xff08;VGES&#xff09;&#xff1a;20V 收集器电流&#xff08;IC&#xff09;&#xff1a;120…

【Spark分布式内存计算框架——Spark SQL】9. Dataset(下)RDD、DF与DS转换与面试题

5.3 RDD、DF与DS转换 实际项目开发中&#xff0c;常常需要对RDD、DataFrame及Dataset之间相互转换&#xff0c;其中要点就是Schema约束结构信息。 1&#xff09;、RDD转换DataFrame或者Dataset 转换DataFrame时&#xff0c;定义Schema信息&#xff0c;两种方式转换为Dataset时…

由浅入深掌握 Python 进程间通信的各类方式

由浅入深掌握 Python 多进程间通信各类方式1、为什么要掌握进程间通信2、进程间各类通信方式简介3、消息机制通信1) 管道 Pipe 通信方式2) 消息队列Queue 通信方式4、同步机制通信(1) 进程间同步锁 – Lock(2) 子进程间协调机制 -- Event5、共享内存方式通信(1) 共享变量(2) 共…

【Bluetooth开发】蓝牙开发入门

BLE 蓝牙设备在生活中无处不在&#xff0c;但是我们也只是将其作为蓝牙模块进行使用&#xff0c;发送简单的AT命令实现数据收发。 那么&#xff0c;像对于一些复杂的使用场合&#xff1a;“车载蓝牙”、"智能手表"、“蓝牙音箱”等&#xff0c;我们不得不去了解底层…

千锋教育+计算机四级网络-计算机网络学习-04

UDP概述 UDP协议 面向无连接的用户数据报协议&#xff0c;在传输数据前不需要先建立连接&#xff1b;目地主机的运输层收到UDP报文后&#xff0c;不需要给出任何确认 UDP特点 相比TCP速度稍快些简单的请求/应答应用程序可以使用UDP对于海量数据传输不应该使用UDP广播和多播应用…

VectorDraw Web Library 10.1003.0.1 Crack

将 CAD 绘图和矢量对象显示添加到您的 HTML5 应用程序。 VectorDraw Web Library 是一个矢量图形库&#xff0c;旨在不仅可以打开 CAD 绘图&#xff0c;还可以在任何支持 HTML 5 标准的平台&#xff08;例如 Windows、Android、IOS 和 Linux&#xff09;上显示通用矢量对象。它…