【VS Code 与 Qt6】QAction 类的一些事

打印 上一主题 下一主题

主题 913|帖子 913|积分 2739

QAction 类表示用户命令的一种抽象,包括命令文本、图标、命令触发后要执行的代码。菜单、工具栏按钮往往存在相同的功能,将这些命令独立抽出来,放到 QAction 以象上,可避免编写重复的代码。比如“文件”菜单下有“保存”命令,工具栏上也会有“保存”按钮。因此,创建一个表示“保存”的 QAction 对象,同时添加到菜单和工具栏中,它们就能共享相同的功能。
以上F话了这么多,就是为了明确 QAction 类的作用。在创建 QAction 实例时,可以通过构造函数传递命令的文本,或图标。如果在调用构造函数时不指定,那么可以用下面这些方法来“补做”:
1、setText 方法:设置命令文本。显示在用户界面上的文本;
2、setIcon 方法:看名识义,就是设置图标;
3、setFont 方法:在呈现命令文本时用的字体。一般不需要特意去指定字体,它会继承应用程序的默认字体;
4、setShortcut:设置命令的快捷键。
QAction 类有个核心的信号:triggered,当用户通过点击或快捷键激活菜单项或工具栏按钮,就会发出 triggered 信号。
 
下面咱们做个简单的例子。这里我用到了 QMainWindow 类来充当主窗口,因为它的“窗口功能”比较完善,创建个菜单栏、工具栏和状态栏的都比较方便。
CMake 文件:
  1. cmake_minimum_required(VERSION 3.20)
  2. # 项目
  3. project(myApp VERSION 1.0.0 LANGUAGES CXX)
  4. find_package(Qt6 REQUIRED COMPONENTS Gui Core Widgets)
  5. # 开启MOC
  6. set(CMAKE_AUTOMOC ON)
  7. # 语言标准
  8. set(CMAKE_CXX_STANDARD 17)
  9. set(CMAKE_CXX_STANDARD_REQUIRED ON)
  10. # 源文件
  11. add_executable(app WIN32 me.cpp)
  12. target_link_libraries(app PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets)
复制代码
me.cpp 文件:
  1. #include <QApplication>
  2. #include <QMainWindow>
  3. #include <QMenuBar>
  4. #include <QMessageBox>
  5. #include <QMenu>
  6. #include <QAction>
  7. #include <QIcon>
  8. // 这三个逗丁用来接收信号的,slot 函数
  9. void onNew();
  10. void onSave();
  11. void onExit();
  12. int main(int argc, char** argv)
  13. {
  14.     QApplication app(argc,argv);
  15.     // 创建主窗口
  16.     QMainWindow win;
  17.     // 窗口标题
  18.     win.setWindowTitle("整活儿");
  19.     // 这样获取,默认会创建空的菜单栏
  20.     QMenuBar* menubar = win.menuBar();
  21.     // 添加“文件”菜单
  22.     QMenu* fileMenu = menubar -> addMenu("文件");
  23.     // 创建三个QAction对象
  24.     QAction *act1 = new QAction("新建", &win);
  25.     QAction *act2 = new QAction("保存", &win);
  26.     QAction *act3 = new QAction("退出", &win);
  27.     // 连接triggered信号
  28.     QObject::connect(act1, &QAction::triggered, &onNew);
  29.     QObject::connect(act2, &QAction::triggered, &onSave);
  30.     QObject::connect(act3, &QAction::triggered, &onExit);
  31.     // 把三个action添加到菜单中
  32.     fileMenu->addAction(act1);
  33.     fileMenu->addAction(act2);
  34.     fileMenu->addAction(act3);
  35.     // 显示主窗口
  36.     win.show();
  37.     // 进入事件循环
  38.     return QApplication::exec();
  39. }
  40. void onNew()
  41. {
  42.     QMessageBox::information(nullptr, "提示", "新建文件");
  43. }
  44. void onSave()
  45. {
  46.     QMessageBox::information(nullptr, "提示", "保存文件");
  47. }
  48. void onExit()
  49. {
  50.     QApplication::exit();
  51. }
复制代码
QMainWindow 的 menuBar 方法用来获取菜单栏(QMenuBar)引用的。但,当窗口中未设置过菜单栏时,它会自动创建一个空菜单栏,并将其引用返回。返回的 QMenu 对象表示菜单,调用它的 addAction 方法就能添加菜单项了。菜单项用 QAction 表示。
onNew、onSave、onExit 这三个函数分别作为三个 QAction 对象的 slot 函数,接收 triggered 信号。
运行后,你会看到,QAction 对象指定的文本,会自动呈现在菜单文本中。

 
通常,为了让菜单命令更直观,咱们会在重要的菜单项上加上图标。接下来给上述三个 action 添上小图标。这里老周介绍一个获取图标的网站,很好用,要啥图标,进去后直接搜索就行,而且可以选择多尺寸下载。比那些要强制登录才能用的骚站好很多。
浏览器打开 Download 1,301,500 free icons (SVG, PNG) (icons8.com)
菜单上的图标,用 16×16 就够了。把图标文件放在与应用程序可执行文件相同的路径下,依次命名为 new.png、save.png、exit.png。
接着,改一下代码,需要用 QAction 带 QIcon 参数的构造函数。
  1. QAction *act1 = new QAction(QIcon("new.png"), "新建", &win);
  2. QAction *act2 = new QAction(QIcon("save.png"), "保存", &win);
  3. QAction *act3 = new QAction(QIcon("exit.png"), "退出", &win);
复制代码
再次编译,运行,效果如下:

 
对于常用的命令,有快捷键能大大提升效率。快捷键需要用到 QKeySequence 类。该类在 QtGui 基础模块中。这个类在调用构造函数时有一种特特简单的用法,就是直接用字符串来描述快捷键。这些字符要求是人类可读性较高的。比如下面这些:
  1. Ctrl+F               // Ctrl + F
  2. Shift+H             // Shift+ H
  3. Alt+W
  4. Ctrl+Alt+E
  5. F5           // 就是 F5   
  6. D            // 就是字母D
复制代码
给上面示例的三个菜单加上快捷键。
  1. act1->setShortcut(QKeySequence("Ctrl+N"));
  2. act2->setShortcut(QKeySequence("ctrl+S"));
  3. act3->setShortcut(QKeySequence("Alt+E"));
复制代码
描述按键的字符串不区分大小写,所以,“Alt+E”和“alt+e”一样。快捷键会显示在菜单命令文本的右边。如下所示

这时候,只要按下 Alt + E,程序就会退出。
 
应用程序除了菜单栏,通常还有工具栏(QToolBar)。QAction 类是命令的抽象,它可以在菜单栏与工具栏之间共用。所以,咱们上面的示例也可以加上工具栏。
  1. // 创建三个QAction对象QAction *act1 = new QAction(QIcon("new.png"), "新建", &win);
  2. QAction *act2 = new QAction(QIcon("save.png"), "保存", &win);
  3. QAction *act3 = new QAction(QIcon("exit.png"), "退出", &win);……// 创建工具栏QToolBar *toolbar = new QToolBar(&win);// 将那三个命令添加到工具栏toolbar->addAction(act1);toolbar->addAction(act2);toolbar->addAction(act3);// 工具栏添加到主窗口win.addToolBar(toolbar);
复制代码
重新编译运行,结果如下:

 
QAction 的 triggered 信号是这样定义的:
  1. void QAction::triggered(bool checked = false)
复制代码
它有个 bool 类型的参数,默认是 false。干吗用的呢?这是处理带 check 功能的菜单用的。就是那种点一下 on,再点一下 off 的那种。咱们在上面的示例中增加一个“开机启动”菜单项。
  1. QAction *act4 = new QAction("开机启动", &win);
  2. // 开启check功能
  3. act4->setCheckable(true);
  4. QObject::connect(act4, &QAction::triggered, &onAutoStart);
  5. fileMenu->addAction(act4);
  6. // 这个是slot函数
  7. void onAutoStart(bool checked)
  8. {
  9.     if(checked){
  10.         QMessageBox::information(nullptr,"提示", "程序开机启动");
  11.     }
  12.     else
  13.     {
  14.         QMessageBox::information(nullptr,"提示","已取消开机启动");
  15.     }
  16. }
复制代码
setCheckable 方法如果传递 true,表示开启 check 功能;若 false,关闭 check 功能。
当可check菜单处于 on 状态时,它前面会显示一个勾。如下图所示:

 
有些时候,菜单命令的默认用户界面不太符合需要。为了方便用户操作,我可能想放一个别的 Widget 上去(比如放个滑块条)。QAction 类做不到这个,但它的派生类可以:QWidgetAction。
咱们在菜单栏上添加一个显示 QSpinBox 组件的命令。
  1. // 创建spinBox组件
  2. QSpinBox *spinbox = new QSpinBox(&win);
  3. spinbox->show();
  4. // 设置一下范围0-300
  5. spinbox->setRange(0, 300);
  6. // 默认显示的值50
  7. spinbox->setValue(50);
  8. // 将它放到工具栏和菜单上
  9. QWidgetAction *act5 = new QWidgetAction(&win);
  10. act5->setDefaultWidget(spinbox);
  11. fileMenu->addAction(act5);
复制代码
QWidgetAction 在实例化后,调用 setDefaultWidget 方法关联要显示在菜单上的组件即可。当然,咱们可以从 QWidgetAction 类派生出自己的类,来实现更高级的需求。这个老周留到下次写水文时再说。
编译运行,看看菜单的最后一项,有趣吧。

 
==========================================================================
好了,今天的话题就聊完了。下面又是老周讲故事时间。
以前老周分享过改 VS Code 全窗口背景的方法,就是设置  元素的背景图,然后适当调一调透明度。
但,如果你不喜欢那样覆盖整个窗口,我只是想打开代码编辑器时才看到背景图呢。嗯,也就是只设置编辑器的背景图。原理一样,都是改 CSS 样式。打开VS Code程序目录下的 resources\app\out\vs\workbench\workbench.desktop.main.css 样式表,添加以下样式:
  1. .monaco-editor, .monaco-editor-background {
  2.   background: center/32% no-repeat url('vscode-file://vscode-app/c:/users/mmm/pictures/bg/20.png') !important;
  3. }
复制代码
对的,就是设置 background 属性,后面的 important 表示强行覆盖,不然不会生效。图片URL 是 vscode-file 协议,加上 vscode-app 前缀,然后就是图片的完整路径。center/32% 表示图片居中对齐,32% 是缩小图片,变为原尺寸的32%,这个你得根据你的图片自己调,调到合适就好。
建议使用透明背景的 PNG 图片,因为太花的图片会干扰你写代码的。CSS 不要用 opacity 来调整透明度,因为这样一调,连代码的透明度也跟着变了,很影响视线,看不清代码,容易导致高度近视。咱们可以在图片上做手脚,就是让原图也具有一定的透明度。
方法是用 PS 打开图片,在图层面板的“不透明度”,改为 15-20% ,具体哪个值你也可以试试,只要看着舒服就行。

设置完后,效果如下:

《初代萌王陪我写代码》,岂不美哉!
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

干翻全岛蛙蛙

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表