commit 225e3636c6d5fe50fb14f2ad3d87751bd6d7c6ac Author: Myth Date: Sun Feb 5 12:23:40 2023 +0800 init: create project diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b5a3fd0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# CMake +/cmake-build* + +# CLion +/.idea diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..303db07 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.0) +project(ZJUConnectForWindows) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +find_package(Qt6 COMPONENTS + Core + Gui + Widgets + Network + REQUIRED + ) + +add_executable(ZJUConnectForWindows WIN32 + main.cpp + mainwindow.cpp + mainwindow.h + resource.qrc) + +target_link_libraries(ZJUConnectForWindows + Qt::Core + Qt::Gui + Qt::Widgets + Qt::Network + ) + +set(DEBUG_SUFFIX) +if (MSVC AND CMAKE_BUILD_TYPE MATCHES "Debug") + set(DEBUG_SUFFIX "d") +endif () +set(QT_INSTALL_PATH "${CMAKE_PREFIX_PATH}") +if (NOT EXISTS "${QT_INSTALL_PATH}/bin") + set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..") + if (NOT EXISTS "${QT_INSTALL_PATH}/bin") + set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..") + endif () +endif () +if (EXISTS "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll") + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory + "$/plugins/platforms/") + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll" + "$/plugins/platforms/") +endif () +foreach (QT_LIB Core Gui Widgets Network) + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + "${QT_INSTALL_PATH}/bin/Qt6${QT_LIB}${DEBUG_SUFFIX}.dll" + "$") +endforeach (QT_LIB) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0a04128 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..2f73d42 --- /dev/null +++ b/main.cpp @@ -0,0 +1,15 @@ +#include + +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QApplication::setApplicationName("ZJU Connect for Windows"); + QApplication::setApplicationVersion("0.1"); + + MainWindow mainWindow; + mainWindow.show(); + + return QApplication::exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..c9b653b --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,365 @@ +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "ui_mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + zjuConnectProcess = nullptr; + networkAccessManager = new QNetworkAccessManager(this); + settings = new QSettings( + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/config.ini", + QSettings::IniFormat + ); + isLinked = false; + isSystemProxySet = false; + logLineCount = 0; + + ui->setupUi(this); + + setWindowIcon(QIcon(QPixmap(":/resource/icon.png").scaled( + 512, 512, Qt::KeepAspectRatio, Qt::SmoothTransformation + ))); + + setWindowTitle(QApplication::applicationName() + " v" + QApplication::applicationVersion()); + + ui->passwordLineEdit->setEchoMode(QLineEdit::Password); + + // 读取配置 + ui->serverAddressLineEdit->setText(settings->value("EasyConnect/ServerAddress", "rvpn.zju.edu.cn").toString()); + ui->serverPortSpinBox->setValue(settings->value("EasyConnect/ServerPort", 443).toInt()); + ui->usernameLineEdit->setText(settings->value("EasyConnect/Username", "").toString()); + ui->passwordLineEdit->setText(settings->value("EasyConnect/Password", "").toString()); + ui->socks5PortSpinBox->setValue(settings->value("ZJUConnect/Socks5Port", 1080).toInt()); + ui->httpPortSpinBox->setValue(settings->value("ZJUConnect/HttpPort", 1081).toInt()); + ui->parseServerCheckBox->setChecked(settings->value("ZJUConnect/ParseServer", true).toBool()); + ui->parseZjuCheckBox->setChecked(settings->value("ZJUConnect/ParseZju", true).toBool()); + ui->useZjuDnsCheckBox->setChecked(settings->value("ZJUConnect/UseZjuDns", true).toBool()); + ui->proxyAllCheckBox->setChecked(settings->value("ZJUConnect/ProxyAll", false).toBool()); + ui->debugCheckBox->setChecked(settings->value("ZJUConnect/Debug", false).toBool()); + ui->autoReconnectCheckBox->setChecked(settings->value("GUI/AutoReconnect", true).toBool()); + ui->reconnectTimeSpinBox->setValue(settings->value("GUI/ReconnectTime", 1).toInt()); + + // 系统托盘 + trayIcon = new QSystemTrayIcon(this); + trayIcon->setIcon(QIcon(QPixmap(":/resource/icon.png").scaled( + 512, 512, Qt::KeepAspectRatio, Qt::SmoothTransformation + ))); + trayIcon->setToolTip(QApplication::applicationName()); + connect(trayIcon, &QSystemTrayIcon::activated, this, [&](QSystemTrayIcon::ActivationReason reason) + { + switch (reason) + { + case QSystemTrayIcon::Context: + trayMenu->exec(QCursor::pos()); + break; + default: + show(); + } + }); + trayIcon->show(); + + trayShowAction = new QAction("显示", this); + trayCloseAction = new QAction("退出", this); + trayMenu = new QMenu(this); + trayMenu->addAction(trayShowAction); + trayMenu->addAction(trayCloseAction); + connect(trayShowAction, &QAction::triggered, this, [&]() + { + show(); + }); + connect(trayCloseAction, &QAction::triggered, this, [&]() + { + QApplication::quit(); + }); + + // 文件-退出 + connect(ui->exitAction, &QAction::triggered, + [&]() + { + QApplication::quit(); + }); + + // 高级-ZJU Rule + connect(ui->zjuRuleAction, &QAction::triggered, + [&]() + { + auto zjuRuleWindow = new QWidget(this); + zjuRuleWindow->setWindowTitle("ZJU Rule"); + zjuRuleWindow->setWindowIcon(QIcon(QPixmap(":/resource/icon.png").scaled( + 512, 512, Qt::KeepAspectRatio, Qt::SmoothTransformation + ))); + zjuRuleWindow->resize(400, 100); + + QString socks5Url = QString("tg://socks?server=127.0.0.1&port=") + + ui->socks5PortSpinBox->text() + + "&remarks=ZJU Connect"; + + zjuRuleWindow->setLayout(new QVBoxLayout()); + + QString socks5UrlLabelText = "你可以将以下订阅链接和你的机场订阅一起添加到 ZJU Rule 中:"; + + auto *socks5UrlLabel = new QLabel(socks5UrlLabelText); + socks5UrlLabel->setTextFormat(Qt::RichText); + socks5UrlLabel->setOpenExternalLinks(true); + socks5UrlLabel->setAlignment(Qt::AlignLeft); + zjuRuleWindow->layout()->addWidget(socks5UrlLabel); + + auto *socks5LineEdit = new QLineEdit(socks5Url); + socks5LineEdit->setReadOnly(true); + zjuRuleWindow->layout()->addWidget(socks5LineEdit); + + QString aboutLabelText = "不明白 ZJU Rule 是什么?请访问这个帖子"; + auto *aboutLabel = new QLabel(aboutLabelText); + aboutLabel->setTextFormat(Qt::RichText); + aboutLabel->setOpenExternalLinks(true); + aboutLabel->setAlignment(Qt::AlignLeft); + zjuRuleWindow->layout()->addWidget(aboutLabel); + + zjuRuleWindow->setWindowFlag(Qt::Window); + zjuRuleWindow->setWindowModality(Qt::WindowModal); + zjuRuleWindow->show(); + }); + + // 帮助-关于本软件 + connect(ui->aboutAction, &QAction::triggered, + [&]() + { + QMessageBox messageBox(this); + messageBox.setWindowTitle("关于本软件"); + messageBox.setTextFormat(Qt::RichText); + QString aboutText = QApplication::applicationName() + " v" + QApplication::applicationVersion() + + "
基于 Qt 编写的 ZJUConnect 图形界面" + + "
作者: Myth" + + "
项目主页: https://github.com/Mythologyli/ZJU-Connect-for-Windows" + + "

ZJUConnect" + + "
ZJU RVPN 客户端的 Go 语言实现,基于 EasierConnect" + + "
<作者: Myth" + + "
项目主页: https://github.com/Mythologyli/ZJU-Connect" + + "

EasierConnect" + + "
EasyConnect 客户端的开源实现" + + "
作者: lyc8503" + + "
项目主页: https://github.com/lyc8503/EasierConnect"; + messageBox.setText(aboutText); + messageBox.setIconPixmap(QPixmap(":/resource/icon.png").scaled( + 100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation + )); + messageBox.exec(); + }); + + // 连接服务器 + connect(ui->linkPushButton, &QPushButton::clicked, + [&]() + { + if (!isLinked) + { + if (ui->serverAddressLineEdit->text().isEmpty()) + { + QMessageBox::warning(this, "警告", "服务器地址不能为空"); + return; + } + + if (ui->usernameLineEdit->text().isEmpty()) + { + QMessageBox::warning(this, "警告", "用户名不能为空"); + return; + } + + if (ui->passwordLineEdit->text().isEmpty()) + { + QMessageBox::warning(this, "警告", "密码不能为空"); + return; + } + + ui->logTextBrowser->clear(); + + zjuConnectProcess = new QProcess(this); + + connect(zjuConnectProcess, &QProcess::readyReadStandardOutput, this, [&]() + { + ui->logTextBrowser->append(QString(zjuConnectProcess->readAllStandardOutput())); + }); + + connect(zjuConnectProcess, &QProcess::readyReadStandardError, this, [&]() + { + ui->logTextBrowser->append(QString(zjuConnectProcess->readAllStandardError())); + }); + + connect(zjuConnectProcess, &QProcess::finished, this, [&]() + { + if (ui->autoReconnectCheckBox->isChecked() && isLinked) + { + QTimer::singleShot(ui->reconnectTimeSpinBox->value() * 1000, this, [&]() + { + if (isLinked) + { + delete zjuConnectProcess; + zjuConnectProcess = nullptr; + + isLinked = false; + ui->linkPushButton->click(); + } + }); + + return; + } + + delete zjuConnectProcess; + zjuConnectProcess = nullptr; + + isLinked = false; + ui->linkPushButton->setText("连接服务器"); + }); + + QList args = QStringList({ + "-password", + ui->passwordLineEdit->text(), + "-username", + ui->usernameLineEdit->text(), + "-server", + ui->serverAddressLineEdit->text(), + "-port", + ui->serverPortSpinBox->text(), + "-socks-bind", + ":" + ui->socks5PortSpinBox->text(), + "-http-bind", + ":" + ui->httpPortSpinBox->text() + }); + + if (ui->parseServerCheckBox->isChecked()) + { + args.append("-parse"); + } + + if (ui->parseZjuCheckBox->isChecked()) + { + args.append("-parse-zju"); + } + + if (ui->useZjuDnsCheckBox->isChecked()) + { + args.append("-use-zju-dns"); + } + + if (ui->proxyAllCheckBox->isChecked()) + { + args.append("-proxy-all"); + } + + if (ui->debugCheckBox->isChecked()) + { + args.append("-debug-dump"); + } + + zjuConnectProcess->start("ZJUConnect.exe", args); + zjuConnectProcess->waitForStarted(); + + isLinked = true; + ui->linkPushButton->setText("断开服务器"); + } + else + { + isLinked = false; + + zjuConnectProcess->kill(); + zjuConnectProcess->waitForFinished(); + + ui->linkPushButton->setText("连接服务器"); + QMessageBox::information(this, "提示", "已断开服务器"); + } + }); + + // 设置系统代理 + connect(ui->systemProxyPushButton, &QPushButton::clicked, + [&]() + { + QSettings proxySettings( + R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings)", + QSettings::NativeFormat + ); + + if (!isSystemProxySet) + { + proxySettings.setValue("ProxyEnable", 1); + proxySettings.setValue("ProxyServer", "127.0.0.1:" + ui->httpPortSpinBox->text()); + proxySettings.setValue("ProxyOverride", ""); + + ui->systemProxyPushButton->setText("清除系统代理"); + + isSystemProxySet = true; + } + else + { + proxySettings.setValue("ProxyEnable", 0); + proxySettings.setValue("ProxyServer", ""); + proxySettings.setValue("ProxyOverride", ""); + + ui->systemProxyPushButton->setText("设置系统代理"); + + isSystemProxySet = false; + } + }); + + // 检查更新 + QNetworkRequest request(QUrl("https://zjuconnect.myth.cx/version.json")); + networkAccessManager->get(request); + + connect(networkAccessManager, &QNetworkAccessManager::finished, + [&](QNetworkReply *reply) + { + if (reply->error() == QNetworkReply::NoError) + { + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply->readAll()); + QJsonObject jsonObject = jsonDocument.object(); + QString version = jsonObject["version"].toString(); + QString url = jsonObject["url"].toString(); + + if (version != QApplication::applicationVersion()) + { + QString text = "有新版本可用:v" + version + + "
点击此处下载"; + + ui->statusLabel->setText(text); + } + } + }); +} + +void MainWindow::closeEvent(QCloseEvent *event) +{ + event->ignore(); + hide(); +} + +MainWindow::~MainWindow() +{ + // 保存配置 + settings->setValue("EasyConnect/ServerAddress", ui->serverAddressLineEdit->text()); + settings->setValue("EasyConnect/ServerPort", ui->serverPortSpinBox->value()); + settings->setValue("EasyConnect/Username", ui->usernameLineEdit->text()); + settings->setValue("EasyConnect/Password", ui->passwordLineEdit->text()); + settings->setValue("ZJUConnect/Socks5Port", ui->socks5PortSpinBox->value()); + settings->setValue("ZJUConnect/HttpPort", ui->httpPortSpinBox->value()); + settings->setValue("ZJUConnect/ParseServer", ui->parseServerCheckBox->isChecked()); + settings->setValue("ZJUConnect/ParseZju", ui->parseZjuCheckBox->isChecked()); + settings->setValue("ZJUConnect/UseZjuDns", ui->useZjuDnsCheckBox->isChecked()); + settings->setValue("ZJUConnect/ProxyAll", ui->proxyAllCheckBox->isChecked()); + settings->setValue("ZJUConnect/Debug", ui->debugCheckBox->isChecked()); + settings->setValue("GUI/AutoReconnect", ui->autoReconnectCheckBox->isChecked()); + settings->setValue("GUI/ReconnectTime", ui->reconnectTimeSpinBox->value()); + settings->sync(); + + if (zjuConnectProcess != nullptr) + { + zjuConnectProcess->kill(); + zjuConnectProcess->waitForFinished(); + } + + delete ui; +} diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..dbef935 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,43 @@ +#ifndef QEASIERCONNECT_MAINWINDOW_H +#define QEASIERCONNECT_MAINWINDOW_H + +#include +#include +#include +#include +#include +#include + +namespace Ui +{ + class MainWindow; +} + +class MainWindow : public QMainWindow +{ +Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = nullptr); + + ~MainWindow() override; + +protected: + void closeEvent(QCloseEvent *e) override; + +private: + Ui::MainWindow *ui; + QSystemTrayIcon *trayIcon; + QMenu *trayMenu; + QAction *trayShowAction; + QAction *trayCloseAction; + QProcess *zjuConnectProcess; + QNetworkAccessManager *networkAccessManager; + QSettings *settings; + + bool isLinked; + bool isSystemProxySet; + int logLineCount; +}; + +#endif //QEASIERCONNECT_MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..5c2d0a8 --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,382 @@ + + + MainWindow + + + + 0 + 0 + 600 + 400 + + + + ZJU Connect for Windows + + + + + + + + 6 + + + + + + + + + + 自动重连 + + + + + + + 调试模式 + + + + + + + + 9 + + + + 连接服务器 + + + + + + + + 9 + + + + 设置系统代理 + + + + + + + 应用 ZJU DNS + + + true + + + + + + + Qt::Horizontal + + + + + + + 解析服务器配置 + + + true + + + false + + + + + + + 应用 ZJU 设置 + + + true + + + + + + + 代理全部流量 + + + + + + + + + + Microsoft YaHei UI + 9 + + + + + + + Qt::RichText + + + Qt::AlignCenter + + + true + + + + + + + + + + 9 + + + + 65535 + + + 1080 + + + + + + + + 9 + + + + Socks5 代理端口 + + + + + + + + 9 + + + + + + + + + 9 + + + + 用户名 + + + + + + + + 9 + + + + 65535 + + + 443 + + + + + + + + 9 + + + + + + + + + 9 + + + + 服务器端口 + + + + + + + + 9 + + + + + + + + + 9 + + + + 服务器地址 + + + + + + + 3600 + + + 1 + + + + + + + 重连时间 (s) + + + + + + + + 9 + + + + 密码 + + + + + + + HTTP 代理端口 + + + + + + + 65535 + + + 1081 + + + + + + + + + Qt::Horizontal + + + + + + + + + 0 + 0 + 600 + 21 + + + + QMenu::item { + padding: 5px 10px 5px 10px; + } + QMenu::item:selected { + background-color: rgb(0, 85, 127); + color: rgb(255, 255, 255); + } + + + + + 帮助 + + + + + + 文件 + + + + + + 高级 + + + + + + + + + + 关于本软件 + + + 关于本软件 + + + + + 退出 + + + + + ZJU Rule + + + + + serverAddressLineEdit + serverPortSpinBox + usernameLineEdit + passwordLineEdit + socks5PortSpinBox + httpPortSpinBox + reconnectTimeSpinBox + parseServerCheckBox + parseZjuCheckBox + useZjuDnsCheckBox + proxyAllCheckBox + autoReconnectCheckBox + debugCheckBox + linkPushButton + systemProxyPushButton + logTextBrowser + + + + diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..901b272 --- /dev/null +++ b/resource.qrc @@ -0,0 +1,5 @@ + + + resource/icon.png + + diff --git a/resource/icon.png b/resource/icon.png new file mode 100644 index 0000000..e386cb0 Binary files /dev/null and b/resource/icon.png differ