你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

一个Linux下最好用的截图工具

[复制链接]
gaosmile 发布时间:2020-8-23 23:18

因为日常Linux办公,经常有截图顺带简单编辑的需求。

在Windows上这项工作基本一直是QQ微信代劳,但是在Linux上这两个都比较拉胯,无奈之下找了几种Linux下的截图工具替代

试了几个比较流行的,感觉下来最好用的算是flameshot,功能齐全运行稳定,图标也挺新潮,操作界面也很简洁,基本毛病没得挑。但唯一的缺点就是:「没有全局热键。」

好在flameshot是个开源软件,下下来源码瞅了一眼,是我熟悉的Qt写的,感觉全局热键这部分可以自己整合一下。

源码中对全局热键的实现只放开了windows,而且从源码来看好像也只预留了接口没实现功能。简单研究了一下,通过一个名为qxtglobalshortcut5的Qt全局热键第三方库可以轻松实现

使用

先把现成的工具放出来吧,伸手党福利:http://kdocs.cn/l/sgGCbHx3wSaM [金山文档] flameshot

  • 复制链接到浏览器直接下载,启动后任务栏会有图标,点击Take Screenshot即可截图 微信图片_20200823231032.png
  • 点击一次截图后,全局热键才可以使用。“Ctrl + F5” 即可触发截图(ubuntu源内自带的qt5.5编译会有这个问题,qt5.7编译出的程序直接启动后全局热键就可以用)。
  • 自己编译的话是有翻译的,这里单程序没有翻译文件,所以都是英文,不过不影响使用。
  • 效果如图:具体的使用快捷键和功能去其他地方查一下吧,我就不搬运了,都是很基本的截图编辑操作,好用得很:
  • 微信图片_20200823231035.png
  • 建议在设置里开机自启,或者加nohup ...... &启动,不占用终端。
  • 这个程序我是用的ubuntu16.04源内自带的库编译的,所以仅仅适用于ubuntu 16.04。换到其他Linux系统不一定能用。其他Linux平台会因为不自带qt或者自带qt库版本不一样导致不能用的问题,最好的办法是自行下载编译,方法如下:2 l% b8 G& _; f& b
编译(Ubuntu 16.04环境)环境准备

Ubuntu16.04自带了一些Qt5.5.1的核心库,但是要编译的话还需要qmake,lrelease等工具,还有x11extras svg等qt插件支持,需要安装:

sudo apt-get install qt5-default
) j1 d% Z+ l; q# A; H0 Jsudo apt-get install qttools5-dev-tools" w8 Z1 a+ @; ~/ Z, v3 ^
sudo apt-get install libqt5svg5-dev2 s5 n) g$ U) l5 x! O' b! K
sudo apt-get install libqt5x11extras5-dev
5 g" }) ^3 l. n/ {: k/ }3 Hsudo apt-get install qtbase5-private-dev
4 x7 b2 v/ q& E

都直接从源里下,这样能保证都是配套同一个版本的。

获取flameshot源码:

地址:http://github.com/lupoDharkael/flameshot.git

git clone http://github.com/lupoDharkael/flameshot.git
, c  F5 K) ]$ `
编译源码cd flameshot' z- D+ P4 c$ [$ s/ G& `( v
mkdir build
1 m0 f5 p0 X1 ]* \cd build 8 `' v4 h& o! R; n& X
qmake ../
7 m/ v  z- @6 \4 s# 报错没有qmake的话,要装上面的库
( l" }6 n: O( W; m6 ]! Q" Dmake -j`nproc`: H3 B" Q. d0 i. V
sudo ln -sf `pwd`/flameshot /usr/bin/flameshot
" F, G: g3 m5 X" o8 \

编译完成后,会生成一个可执行文件flameshot,可以直接放一个软连接到/usr/bin下面

增加全局热键功能

一、获取qxtglobalshortcut5项目到此项目中

# 离开刚才的编译目录
4 M; s8 V/ D6 Z  L4 h1 icd ../   l, ]: K/ t: X9 |6 D
# pwd: ~/flameshot
- D5 u  o; d, ~# zgit clone http://github.com/ddqd/qxtglobalshortcut5.git
' r) f" l! d4 v) T: A4 ~" W

flameshot项目和qxtglobalshortcut5这个项目都是qt的pro管理的,整合起来非常方便 在获取到qxtglobalshortcut5项目后,flameshot项目下就有这个玩意儿:

微信图片_20200823231039.png

qxtglobalshortcut5的实现已经相当完善了,引入后一行都不需要改,只需要改写flameshot项目 在flameshot.pro文件中添加一行:include(qxtglobalshortcut5/qxt.pri)

QT  += core gui widgets network svg) ^. r* T8 L( T# ?7 @- U6 F3 Y

" m( r6 K! f- d1 _4 ~* Punix:!macx {" u% _: |  u0 K. A: f2 k- Y$ l
    QT  += dbus) N' E, W) T7 z
}
9 C* Y+ m4 ?8 X, Z" c8 Z( h+ _* L& b
CONFIG += c++11 link_pkgconfig* m; F3 r, ~8 V; P- }4 a
include(qxtglobalshortcut5/qxt.pri)   # 这一行是新加的
. `! o' E( z! a- [/ {#CONFIG += packaging   # Enables "make install" for packaging paths
$ ?1 Q% s1 @$ J' \5 G5 j. ?% [4 x0 a- D- ~( j/ F
TARGET = flameshot) c8 |! ?# O- i8 Q1 A) N1 a9 U1 y
TEMPLATE = app/ R9 X& a6 E* {' x8 e: ~- ~6 |+ y+ G

二、源码里注册全局热键

打开src/core/controller.cpp这个文件,找到Controller的构造函数,在这里注册全局热键:

Controller::Controller() : m_captureWindow(nullptr) {
1 ?8 W. [; I  ]' D    qApp->setQuitOnLastWindowClosed(false);
, @. o2 w5 G* G6 o  A8 ?* z9 c* P% R$ d) H5 b
    // init tray icon
0 H$ _6 I! b/ U" J, J. x3 z0 |#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)& R- B6 _/ {$ ]6 w  z- E' Z
    if (!ConfigHandler().disabledTrayIconValue()) {( m, F+ O( t1 g8 A% p4 q3 r
        enableTrayIcon();/ \1 m0 Y- C0 K0 K
        }
, O0 Y5 N# S! ]* N6 W% R6 R+ A; j        /** 注册全局热键! */; I. T2 Q0 c  n) b2 }9 h: k( r/ d0 i
        QxtGlobalShortcut* shortcut1 = new QxtGlobalShortcut(QKeySequence("Ctrl+F5"), this);
/ l0 S% r+ u( F7 {5 Y. F2 E/ R) Z  c        /** 全局热键触发的函数! */0 b9 q) Q# O/ c' u+ ?
        connect(shortcut1, SIGNAL(activated()), this, SLOT(shortcutActiveCapture())); % Q+ V4 v# g+ ^
#elif defined(Q_OS_WIN); s4 m- r& F7 q% B" r; [: w' m5 {
    enableTrayIcon();& c% d$ x. D: M8 n; W

. k8 f; I  Y) r* X5 y6 y    GlobalShortcutFilter *nativeFilter = new GlobalShortcutFilter(this);, Z$ `' z+ W! E
    qApp->installNativeEventFilter(nativeFilter);& I% W; L' C% R2 G
    connect(nativeFilter, &GlobalShortcutFilter::printPressed,7 g% o* I/ V% S/ j4 ]+ ^  l9 ]
            this, [this](){- c) w9 q" o( n( B( H
        this->requestCapture(CaptureRequest(CaptureRequest::GRAPHICAL_MODE));. E7 ~0 C/ P0 j( W, c, @( j
    }); 5 d# `. h" ]$ U% n3 B, r
#endif- X( Y! X. i: W8 k1 o4 |* o

5 t! O. H4 W* R: A9 _2 g' G    QString StyleSheet = CaptureButton::globalStyleSheet();6 l2 _; h6 [0 x- y" A
    qApp->setStyleSheet(StyleSheet);) v" g0 d6 I% B* a3 t. y
}
& O; t! Q" E* N5 K+ y% h3 A" L" f

这里除了注释的两行是我加的,其他都是原来的代码,这个库支持字符串的形式注册全局热键,Ctrl+F5可以换成你自己喜欢的。

因为没有在Window上测试过们这里只加给了Q_OS_LINUX环境,理论上这个全局热键的库各平台都是通用的,不过我只需要Linux。

三、全局热键的处理函数

上面给shortchut1注册了一个槽函数shortcutActiveCapture,这个函数还没有实现,这个函数的功能很简单,只需要调用截图函数就行,可以查一下我们点击截图触发的是哪一个函数,我们也调用同一个函数即可:

  • src/core/controller.h 文件,在头文件里,添加函数声明:
    4 K% q9 H8 i( T  S; L$ S
private slots:8 p. z7 m3 G7 t$ L6 L
    void startFullscreenCapture(const uint id = 0);* ]! J$ ?' n5 q/ ]
    void startVisualCapture(const uint id = 0,9 T( s: J3 {2 {9 _* Q
                             const QString &forcedSavePath = QString());
$ e" q. u( B/ C! b: y! }7 H    void startScreenGrab(const uint id = 0, const int screenNumber = -1);
9 R1 x* @% R* ^3 I8 [, O1 ?, ?6 i" m; q; V
    void handleCaptureTaken(uint id, QPixmap p);
$ r; c, z. n" D$ o% `5 `% z    void handleCaptureFailed(uint id);0 f, c6 e3 g( g8 O$ h4 D' u/ @/ J
    void shortcutActiveCapture(); //这一句是追加的/ r9 Y5 B0 }$ f6 \9 C
  • src/core/controller.cpp文件,在实现文件里,添加函数实现:
    - E2 {$ @9 p4 R" z6 f( B0 e
void Controller::shortcutActiveCapture()  }; ~" f  O8 p6 V8 T
{& Q) V. W4 t  K6 }
    this->startVisualCapture(0,QString());
* K5 r) {' M/ h1 A/ f2 @}* i; a6 K/ E1 l6 K0 A; O

「四、重新编译运行」

进入到刚才的编译目录,重新执行qmake,make编译就可以了。

cd build / Q( F" T1 b+ j$ j5 Q7 W
qmake ../2 H/ @' k" ?) U0 y+ _
make # D4 Y4 V0 ^* n; }4 r0 p1 Q5 u$ B

编译好后可以试一下,生成的可执行程序运行后可以通过全局热键Ctrl+F5进行截屏编辑操作。

这个改动非常简单,通篇使用的是Ubuntu源内自带的工具和库。即使没怎么接触过qt的人,按照上面的套路也可以把这个工具轻松整出来。

如果是Qt老炮,可以通过本地编译出来或者本地安装的其他版本的qt编译这个程序,目前尝试qt5.5.1全局热键还是有点问题的,上面也提到了。我本地用的qt5.7没有这个问题。

存在问题:失去焦点就消失的窗体

理论上可以点击截图的地方,完全用不到全局热键,只有一种场景对全局热键截图这个功能有刚需:失去焦点窗体就消失的情况。比如,你在chorme浏览器的某个标签页上右键弹出一个对话框,你想截图这个对话框里的内容,但是一旦你鼠标去点击截图的按钮,这个对话框就会因为失去焦点而消失。这个时候就需要截图全局热键的功能来实现: 微信图片_20200823231042.png

或者对一些鼠标悬停才会显示的内容tooltips的截图也是这样:

微信图片_20200823231045.png

但遗憾的是,在Linux平台上,这个全局快捷键截图仍然不能非常完美的解决所有“失焦即焚”窗体的问题

比如说你随便打开一个窗口,鼠标挪到左上角随便点一个选项卡(文件、修改、视图等等的),当他出现菜单时,你想截图这个菜单的内容,你就会发现全局热键不好使了:

微信图片_20200823231048.png

当这个红框窗体拿到焦点的时候,全局热键就不好使了,为了让全局热键生效让他失去焦点,这个窗体又会消失。进入到一种无法截图的尴尬境地。(我这张是对着虚拟机截出来的)

但这个问题并不是qxtglobalshortcut5实现的问题,而是X11本身的限制,一个直观的证据就是:在这种情况下,你键盘上的PrintScreen按键也会失效。

为了这个问题大概看了下qxtglobalshortcut5的Linux部分的实现,确实已经是x11提供的XGrabKey所能提供功能的极限了,如果硬要让自己全局热键的优先级高于窗口管理器,可能得写驱动级别的程序来搞。

存在问题2:输入文字不支持输入法

文字只能输入英文,这个也比较坑,目前还在想办法,目测可以用加载ibus/fcitx输入法插件的方式解决,后期解决后回来更新,有了解的大佬欢迎不吝赐教。


8 i% F% G0 o& C$ _
收藏 评论0 发布时间:2020-8-23 23:18

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版