qt5-入门-信号槽理解+QMainWindow

参考:

Qt 深入了解信号槽_w3cschool

https://www.w3cschool.cn/learnroadqt/wz3t1j47.html

Qt MainWindow_w3cschool

https://www.w3cschool.cn/learnroadqt/uqjl1j4b.html

本地环境:

win10专业版,64位


信号槽

最简单的例子:写一个按钮,点击可以关闭主窗口

cpp 复制代码
#include <QPushButton>
...
QApplication a(argc, argv);
QPushButton *btn = new QPushButton("Quit");
QObject::connect(btn, SIGNAL(clicked()), &a, SLOT(quit()));
btn->show();
return a.exec();
  • connect()是在QObject中实现的,所以只要继承了QObject就可以用,并不是只有GUI可用的

  • 一个信号可以与多个槽相连(写多条connect语句,sender是同一个),这些槽都会被调用,但是调用的顺序是不确定的

  • 多个信号可以连接到一个槽(多条connect语句,receiver是同一个),此时只要有任意一个信号发出,这个槽函数就会被调用

  • 一个信号可以连接到另一个信号(slot写的是一个signal),此时表示当第一个信号发出时,第二个信号也被发出

  • 槽也可以取消连接,就是把connect换成disconnect,参数是一样的。不过很少这么写,因为delete一个对象后,Qt会自动取消所有连接到这个对象的槽

  • 如果信号的参数多于槽的参数,那么信号多出的参数会被跳过

    比如const QString &就会被忽略到,传不进去

    cpp 复制代码
    connect(ftp, SIGNAL(rawCommandReply(int, const QString &)), this, SLOT(checkErrorCode(int)));

Meta-Object系统

提供了两个关键作用:信号槽和内省。内省 也称为反射,就是允许程序在运行时获得meta-information,就是类的相关信息。标准c++没有这些动态的meta-information,所以Qt使用了一个独立、用c++实现的工具:moc。Meta-Object系统的工作过程是:

  1. Q_OBJECT声明了一些QObject子类必须实现的内省的函数,如tr()等
  2. Qt的moc实现了Q_OBJECT宏声明的函数和所有信号
  3. QObject的成员函数connect()和disconnect()使用这些内省函数实现信号槽的连接

QMainWindow简单使用

QMainWindow的结构

Qt支持多个工具条显示;Dock window areas是停靠窗口的显示区域,可以放些工具箱什么的。

QAction

QAction能够根据添加的位置变形,比如放到菜单中就是一个菜单项;放到工具条,就是一个按钮。

举例:假设想弄一个打开命令,这个命令可以放到Menu bar和ToolBar areas中,执行的都是打开文件的命令(先不写connect,只写ui部分)。

文件结构:

实现效果:

按住键盘Alt+f(指定的快捷键),可以看到:

mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

// 提前声明
class QAction;

class MainWindow : public QMainWindow{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
// 增加一个QAction指针对象
private:
    QAction *openAction;
};

#endif // MAINWINDOW_H

mainwindow.cpp

cpp 复制代码
#include "mainwindow.h"
#include <QAction>
#include <QMenuBar>
#include <QToolBar>

MainWindow::MainWindow(QWidget *parent) : QMainWindow (parent) {
    // 第一个参数是对动作的描述,是显示的文本信息
    // 第二个参数是parent(父组件),通常是this指针。当父组件被销毁时,与其相关的QAction会自动销毁
    openAction = new QAction(tr("&Open"), this);
    // 设置快捷键
    openAction->setShortcut(QKeySequence::Open);
    // 状态栏的提示内容
    openAction->setStatusTip(tr("打开一个文件"));

    QMenu *file = menuBar()->addMenu(tr("&File"));
    file->addAction(openAction);

    QToolBar *toolBar = addToolBar(tr("&File"));
    toolBar->addAction(openAction);

}

MainWindow::~MainWindow(){}

main.cpp

cpp 复制代码
#include <QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    MainWindow w;
    w.show();

    return a.exec();
}

添加响应也很简单。

cpp 复制代码
// mainwindow.h
// 增加
private slots:
    void open();

// mainwindow.cpp
// MainWindow::MainWindow
connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
...
void MainWindow::open() {
    QMessageBox::information(NULL, tr("这是标题"), tr("这是内容"));
}

点击菜单栏或者工具栏就会弹出信息窗口,如下:

其中使用了中文,是因为在mainwindow.cpp的头部加入了宏:

cpp 复制代码
#pragma execution_character_set("utf-8")

为QAction添加图标

使用自定义的图标

在项目上右键点击,选择Qt-Qt Resource File

命名为res,然后可以看到项目中多了一个:

qrc是Qt Resource Collection的缩写,是一个XML文件。然后先修改前缀,再添加文件。

然后在项目名称上右键添加文件。此时文档结构:(Other files和Resources都是QtCreator自己弄的分类,磁盘上是没有这样的文件夹的)

修改mainwindow.cpp

cpp 复制代码
openAction->setIcon(QIcon(":/pic.jpg"));

解释:因为使用qrc文件定义的,所以路径以:开头;因为定义了前缀(prefix)是/,所以要接着写/,然后再写路径。

效果是:

需要注意的是,QToolBar的图标大小默认是32x32,菜单默认是16x16,如果提供的图片小于要求的尺寸,Qt不会放大;反之Qt会自动缩小尺寸

使用Qt自带的

需要增加的代码是:

cpp 复制代码
    // 设置icon
    //enum QStyle::StandardPixmap Icon = (enum QStyle::StandardPixmap)42;
    enum QStyle::StandardPixmap Icon = static_cast<enum QStyle::StandardPixmap>(42);
    openAction->setIcon(QApplication::style()->standardIcon(Icon));

其中注释掉的转换会提示warning,因为是老式风格。用static_cast就可以了。

42是图像的编号,完整的图象是:

参考这里:

Qt学习笔记之--Qt内置图标一览表_qt自带的图标-CSDN博客

https://blog.csdn.net/wh_19931117/article/details/80444107

代码基本不用改,就是MainWindow.cpp里增加#include < QStyle>可以解决报错。

相关推荐
api茶飘香27 分钟前
守护应用边界:通过反射API实现安全的输入输出过滤
java·开发语言·python·安全·django·virtualenv·pygame
杀死一只知更鸟debug28 分钟前
策略模式的小记
java·开发语言·策略模式
efls11129 分钟前
Qt_了解Qt Creator
开发语言·qt
请揣满RMB33 分钟前
Qt常用控件——QRadioButton和QCheckBox
开发语言·c++·qt
阿巴~阿巴~33 分钟前
C_深入理解指针(五) —— sizeof和strlen的对比、数组和指针笔试题解析、指针运算笔试题解析
c语言·开发语言·数据结构·算法
爱吃桃子的ICer1 小时前
[UVM]3.核心基类 uvm_object 域的自动化 copy() compare() print() pack unpack
开发语言·前端·ic设计
ever_up9733 小时前
EasyExcel的导入与导出及在实际项目生产场景的一下应用例子
java·开发语言·数据库
吴天德少侠3 小时前
c++返回一个pair类型
开发语言·c++
ok!ko4 小时前
设计模式之工厂模式(通俗易懂--代码辅助理解【Java版】)
java·开发语言·设计模式
学地理的小胖砸4 小时前
【GEE的Python API】
大数据·开发语言·前端·python·遥感·地图学·地理信息科学