Sandboxie-沙箱软件-Plus版本(Qt)-主框架程序

文章目录

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
  • 1

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

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

目录之下生成了对应的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.作者答疑

如有疑问,敬请留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值