File | Date | Author | Commit |
---|---|---|---|
docs | 2024-04-15 |
![]() |
[d0885e] feat: update README and i18n |
translations | 2024-04-15 |
![]() |
[d0885e] feat: update README and i18n |
README.md | 2024-03-27 |
![]() |
[0968e8] feat: update v1.4.0 |
Sunny is a beautiful and useful "Screenshot & Pinning" software, also supports "Screen Recognition" and "OCR" software, supports Windows, MacOS, Linux operating systems.
This program will be developed and maintained for at least ten years starting in 2023 and is free of charge!
Official website: https://sunny.xmuli.tech | Author: 偕臧
Download: App Store : Microsoft Store / Deepin Store / UOS Store / Spark Store
Feedback on bugs, suggestions or ideas to help improve and join the community:
👉 Sunny 截图是一款简洁且漂亮的截图的软件工具,亦支持【图片翻译】和【OCR】
Downloading from GitHub Release is highly recommended for the fastest and most stable updates. After downloading the file, right-click on the file's properties to verify its uniqueness and make sure the file has not been tampered with;
Keys | Description | Mode |
---|---|---|
F6 | Window activation capture scree | Global |
Ctrl + F6 | Delay screen capture | Global |
Shift + F6 | Custom size capture screen | Global |
🐱🐉 | ||
Esc | Quit Screenshot | Local |
Tab | Select the depth of the detected sub-window rectangle | Local |
` / ~ | Show / Hide information about the current window ( ExeName / Path / Size / PID / HWnd ...) | Local |
Ctrl + Shift + S | Shortcut keys to quickly save to a specified path | Local |
←, ↓, ↑, → ( A, S, W, D ) | Move selection 1px | Local |
Ctrl + ←, ↓, ↑, → | Extended selection 10 px | Local |
Shift + ←, ↓, ↑, → | Shrink selection 10 px | Local |
On Window 10/11+ systems, also available for direct download from the Microsoft Store
The Deep Community, Unicom OS Store, is now available for direct download.
Direct download from the software store, Thanks to XXTXTOP for helping to stock this Openkylin Store!
as well as the three-way Starfire Store, also available for direct download
Translation of documents, submission of PR → *.ts
Share the joy
On the night of v1.3 release, I remember the downloads were 900+; after the release, I went to bed.
The next morning, the number of downloads was 1k, 1.1k; at noon, it was 1.2k; at night, it was 1.3k;
The third day it's 1.4k.
Day four is 1.5k.
... ...
The day before yesterday, I came back to see, well, still 1.5k, everyone had a good time.
The day before yesterday, it was 1.6k.
The day before yesterday, it was 1.7k.
Yesterday's arrived 1.7k
Today's arrived 1.8k, commemorative punch card
Of all the software written, the total number of downloads is not the largest, but the short-term growth rate is the fastest ヾ(≧▽≦*)o.
很久之前就想些一个软件截图的软件,目前一共写如下三个层级的难度作品,提供大家参考
项目 | 描述 | 开发经验 |
---|---|---|
ShotX | 功能极简的截图工具 | 简易,新手级的截图,适合初学 Qt/C++ 入门 |
FLIPPED | 简洁且漂亮,功能完整的截图软件;隐私安全,无任何联网功能 | 高级难度,属 Qt/C++ 数年经验的进阶作品,在借鉴同类作品的代码时,可于探索中独立完成的一个大的软件 |
Sunny | 一款简洁且漂亮的截图的软件工具。亦支持图片翻译和OCR;已上架微软商店,深度/统信商店,及三方的星火商店等 | 专业级作品,适合已多年沉浸研究 Qt/C++ 经验,随心所欲写任意所需功能,属于商业级的成熟作品,是本截图系列的最高水准之作 |
注: ShotX,FLIPPED,Sunny 这三款均支持跨平台 Windows / MacOS / Linux。
笔记: Sunny = FLIPPED的功能重构 + 代码重构 + UI重构 + 网络功能(图片翻译+OCR)+ 上架应用商店 + 后续新功能;而 ShotX 是最早的练手探索
在写和发布的后的期间,也遇到很多私聊请教 、 邮件沟通某个功能实现?反馈 Bug 和给出使用心得和建议;都给答疑了,但想来可写为一整篇,中间遇到的困难点都写出来,公开出来提供后来者参考。
编译环境
💻 MacOS 13
📎 Qt 5.15.2
📎 gcc/g++ 9.2
📎 gdb8.3
💻 Ubuntu 22.04
📎Deepin 20.9-23+
📎 Qt 5.15.2
📎 gcc/g++ 9.0
📎 gdb8.0
💻 win10 22H2
📎 Qt 5.15.2
📎 Visual Studio 2022
📎 C++17
详细解答这些问题 《分享如何拥有一份私人的『开源代码签名证书』》,并且指导最后如何签名。
篇幅太长,单写了一篇,包含详细上架 Windows Store, Deepin/UOS Store, 三方 星火商店等。
👉 《Sunny截图上架Microsoft Store及Linux商店流程的指北》
Note:
个人作品上架微软商店的流程很折磨,最后上架成功后也是拨开云雾;
若是文章对你有价值,亦可帮我积累Sunny的微软信誉,或者在深度商店的好评,甚至感谢🙇 ;
Windows 用户推荐的下载 👉 Sunny_setup_msvc_1.3.0_x64.exe
介绍多种平台和格式:①Windows:绿色便携版和安装包 .exe
②MacOS:.app
和 .img
③Linux: 绿色版、 .deb
和 .AppImage
『问题』Linux 如何构建打包为 .deb 文件、如何打包为通用的 .AppImage 格式?
Linux下又多种打包 .deb
打包方法:
〖方法一〗通过 ldd.sh + Sunny.sh 两个脚本打包依赖,参考《QT 项目在 Linux 平台上面发布成可执行程序》
〖方法二〗通过 dh_make
+ dpkg-buildpackage
命令《Linux 中用 dh_make 将 Qt + CMake 项目打包为 deb 文件》
〖方法三,最推荐〗通过 CMake 的 cpack
命令,那样就不需要填写 debian 文件夹下的 control 等文件,直接拷贝相关资源文件过去。 CMakeLists.txt 底部加上 CPack 的相关代码,核心如下:
```cmake
# CPACK: General Settings
set (CPACK_GENERATOR "TBZ2")
set (CPACK_PACKAGE_NAME "${project_name}")
set (CPACK_PACKAGE_VERSION "${project_version}")
set (CPACK_PACKAGE_VENDOR "https://github.com/XMuli")
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple and beautiful screenshot software tool for Windows, MacOS and Linux")
set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
set (CPACK_PACKAGE_CONTACT "https://sunny.xmuli.tech")
# 设置Debian软件包的依赖关系
set (CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5x11extras5, libqt5svg5")
set (CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
set (CPACK_DEBIAN_PACKAGE_SHILIBDEPS ON)
include(CPack)
```
Linux下有多种打包 .AppImage
打包方法
```bash
$ ../linuxdeployqt-continuous-x86_64.AppImage Sunny -appimage
$ sudo apt install libfuse2
但是由于过于作者的固执坚守旧的版本,所以无法使用,理由和可能的解决如下:
https://github.com/probonopd/linuxdeployqt/issues/340#issuecomment-932712016
即:使用linuxdeploy和linuxdeploy-plugin-qt
https://github.com/BearKidsTeam/thplayer/blob/master/.github/workflows/linux.yml#L54
$ sudo apt update
$ sudo apt install qtbase5-dev qtmultimedia5-dev libqt5multimedia5-plugins
$ sudo add-apt-repository universe
$ sudo apt install libfuse2
$ wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
$ wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
$ chmod +x linuxdeploy*.AppImage
$ mkdir build && cd build
$ cmake ..
$ cmake --build . -j$(nproc)
$ cd ..
$ ../linuxdeploy-x86_64.AppImage --appdir AppDir -e bin/Sunny -d bin/resources/cpack/tech.xmuli.sunny.desktop -i bin/resources/logo/logo.svg --icon-filename tech.xmuli.sunny -p qt -o appimage
$ ./linuxdeploy-x86_64.AppImage --appdir AppDir -e build/thplayer -d assets/thplayer.desktop -i assets/thplayer.svg --icon-filename thplayer -p qt -o appimage
$ mv TouHou_Player*.AppImage thplayer-linux.AppImage
```
『问题』如何书写 .yml 的脚本,通过 GitHub 的Action 资源,自动打包构建生成 Release 呢?
通过写三个系统的 .yml 脚本,路径必须是 .github/workflows
,随着时间的流逝⌛,想要持续构建对应的云系统和 Kit 也必须更新,文档和版本参见 images ,直接往 .yml 修改;这是一个实际可跑的脚本 *.yml 都是可以编译成功的,失败可能是额度时间不够了,如某次成功的示例,可看到头像是 GitHub 的头像发布的 Release-v6.1 ;
单纯实现亚克力效果不难,难在Linux和 MacOS 上也能实现这个效果?这是当时的一些探索和经验,总结了四种方法放置于 GitHub - AcrylicWindow
也折腾过,难度也很大,后来发现对于截图,费力可以实现,但是没必要,成本太大;结论:这样现成的没有,目前效果和跨平台都最佳的方案是framelesshelper, 有时放弃也是一种解决方案。
ui->retranslateUi(this)
函数?不重启软件便可以切换语言对于有有 .ui 的部分,可以通过 《Qt 项目(CMake)设置国际化支持》来解决。对于存手写的控件实现的,且大致实现的思路是:
下拉框中切换语言时,发射信号 → 全局单例 → 信号和槽函 → 到主窗口的槽函数,在里面进行重新加载语言,所有相关的控件的默认文本,都写在这个函数里面,便可以不重启软件,直接实现语言切换成功
全程不会弹 UAC 弹窗,不需要管理员权限就可以使用所有功能,也不会中途提权,仅普通用户权限即可,包括导向安装,静默安装,使用卸载;
MacOS 除了系统自带的截图支持外,至今没有任何一个三方软件可以做到这点,包括大厂等某企鹅的截图的,无解。根原是属于此苹果接口没公开,至少没人能够发现。
一个难点是再 MacOS 上也要和再 Windows 的效果保持一致,于是对不同风格进行对比,但 Fusion 又会倒是 Setting 窗口非原生的样式,但好在十分接近;选取一个平衡点。另外还手绘画了一个二十多个自定义或者复杂控件。
也花了大力气来探究,在完成一次截图之后,内存的占用会在合适时机自动释放出来;这是定位在消耗内存的变量;开发环境显示器为 4K 27 寸 + 3K笔记本双屏;
可采用奇异递归模板的方式,然后添加一个宏展开为友元类;多个单例都只用写一份,而前提是需要对 《C++ 类的六个特殊成员函数》 很熟悉,才能理解,属于优雅的一种实现。
日志可以通过配置文件修改,若是遇到传说的崩溃,亦会自动生成 .dmp 和 崩溃原因;
转储文件存放: C:/Users/用户名/AppData/Local/XMuli/Sunny/cache/Sunny_Dumps/dump_2024_02_29_11_31_30_714.dmp
实现方法可通过 WIN API 来实现
cpp
#ifdef _MSC_VER
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);//注冊异常捕获函数
#endif
额,你没接触过 DUMP,完全不会对其进行解剖分析?也简单写了一个使用 WinDbg 进行入门
《WinDbg:入门分析 dmp 文件『一』》、《WinDbg:调试之附加进程生成 dmp『二』》
可以通过共享内存QSharedMemory 和系统信号量 QSystemSemaphore,双重保证程序在一台终端上,仅会运行一个;
也能杜绝很罕见的一种情况,即使上次程序崩溃之后,但仍有残留的僵死进程,被误判当前没有启动。严谨(中指推一下眼镜)
```cpp
QString uniqueKey = "SunnyUniqueKey"; // 使用唯一的标识符来创建共享内存和系统信号量
QSharedMemory sharedMemory;
sharedMemory.setKey(uniqueKey);
// 尝试附加到现有的共享内存并分离
if (sharedMemory.attach()) {
sharedMemory.detach();
}
// 尝试创建共享内存,如果已经存在,表示已经有一个实例在运行, 判断是为了确保在同一台计算机上只能运行一个相同实例的程序。
if (!sharedMemory.create(1)) {
qDebug() << "There is already an instance of the application running (by QSharedMemory)!";
return 1;
}
// 创建系统信号量, 再尝试获取系统信号量,如果已经被其他实例持有,程序就退出, 判断是为了确保在多个进程同时启动时,只有一个进程能够继续执行。QSystemSemaphore用于创建系统信号量,如果系统信号量已经被其他实例持有(比如由于上一次程序异常退出导致信号量未被释放),则acquire函数会返回false,
QSystemSemaphore systemSemaphore(uniqueKey, 1, QSystemSemaphore::Open);
if (!systemSemaphore.acquire()) {
qDebug() << "There is already an instance of the application running (by QSystemSemaphore)!";
return 1;
}
// ...程序其它逻辑
// 释放系统信号量
systemSemaphore.release();
```
分析和解决方案《Qt新弹窗不响应键盘按键,难道也是无焦点?》
分析和解决方案《创建 QKeySequenceEdit() 后,显示方块■◆乱码》,还是多看下 Qt Assistant 解围粗心。
解决方案为《VS2022 And QtCreator10 调试 Qt 源码教程》、《VS2017调试Qt源码》
虽简单,但移除标志位容易忘却,这里简单列举一下《C++ 标志位使用:校验、添加、删除》
那日强迫症,且需要删除空格才能解决,属实比较稀少;记录下解决方案 《Misleading indentation; statement is not part of the previous ‘if‘》
展开讲解一下,若未接触过,属会用会看即可《Lambda 表达式详解》
Release实际也是可以调试的,新手容易不知晓,知晓的亦可能会翻车,值得记录下;属于 Release / Release with Debug Info / Debug 的差异《Visual Studio 断点调试之箭头偏移进错函数,捉虫记》
详细示例《Visual Studio 2019 进行远程调试》
参考《 愿编程不再乱码(含Qt)-根因深究》,以及 QtExamples 的 "「第 6 章」 QT / IDE 乱码根因和解决"
开源三方库引入,想要优雅,基本 git submodule
或 git treemodule
命令之间二选一;推荐前者,理由为 《git submodule 基本用法》
比较犹豫和纠结的一个问题,两种都试过;现总结为:项目初期使用自带的 QDebug 即,不够用再写一个类,和宏封装一套,满足需求即可,勿跑偏,功能才是重点。最后期可以选用三方库引入:
一点经验参考 《Log:日志选型调研『一』》、《Log:日志之 Spdlog 极简用法示范『二』》、《Log:日志之 Spdlog 核心构成『三』》
现在已经幸福多了,ChatGPT 横空出世,已经可以解答了,故介绍一些高频或者重点宏,自己结合去搜🔍
CMake 的重要宏:《CMake 设置 Target 输出目录和后缀名》、《CMake 之 BUILD_SHARED_LIBS 和 CMAKE_BUILD_TYPE 用法教程》
Windows 的重要宏:《LPSTR/LPCSTR/LPTSTR/HWND/HANDLE/HMODULE/HINSTANCE 等含义和区别》
If it helps you, or find it useful, you can click on the item's⭐Star 🍴 Fork of the two icons, conveniently lift the hand between, said a point of praise the hand, There is a fragrance in your hand;The next best thing is to buy me a cold Coke.
QtExamples Welcome star
⭐ and fork
🍴 to this series of C++ / QT / DTK
studies, Here you can learn the experience of how to write one of this software by yourself, it's a complete series and it's free!