QT系列教程(9) 主窗口学习

简介

任何界面应用都有一个主窗口,今天我们谈谈主窗口相关知识。一个主窗口包括菜单栏,工具栏,状态栏,以及中心区域等部分。我们先从菜单栏说起

菜单栏

我们创建一个主窗口应用程序, 在ui文件里的菜单栏里有“在这里输入”的一个菜单,我们双击它输入“文件(&F)”, 这样通过点击alt + F 就可以弹出文件菜单。点击文件菜单,同样会弹出“在这里输入”,我们双击它编辑输入“新建文件(&N)”,可以在右侧的属性栏里为其添加一个图标,同样,我们再添加一个“显示Dock(&D)”的菜单。我们再从左侧的控件Containers里拖动Dock Widget到中心区域,在dock widget中添加一个按钮,一个fontComboBox,一个QTextEdit。DockWidget添加的控件并不会影响主窗口的centralwidget, 我们在centralwidget中添加一个QMdiArea控件。
https://cdn.llfc.club/1665046632168.jpg
我们可以选择Action Editor中的两个action,分别为其添加槽函数,右击actionnew_N选择转到槽,然后选择trigger信号,Qt会自动生成槽函数代码
https://cdn.llfc.club/1665047247148.jpg
同样的道理为显示dock菜单添加槽函数,然后分别实现两个槽函数

void MainWindow::on_actionnew_N_triggered()
{
    qDebug() << "新建文件..." << endl;
    QTextEdit * textEdit = new QTextEdit(this);
   auto childWindow = ui->mdiArea->addSubWindow(textEdit);
   childWindow->setWindowTitle(tr("文本编辑子窗口"));
   childWindow->show();
}

void MainWindow::on_actionshowdock_triggered()
{
    qDebug() << "显示dock widget" << endl;
    ui->dockWidget_2->show();
}

因为QMdiArea是一个多窗口控件,这样我们每次点击新建菜单就会在窗口的中心部件中创建一个子窗口,多次点击会生成多个子窗口。点击显示dock菜单就会显示dockwidget。

我们可以在代码中添加菜单并创建菜单点击后的回调函数

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QMenu* editMenu = ui->menubar->addMenu(tr("编辑(&E)"));
    editMenu->addSeparator();
    QAction * action_Open = editMenu->addAction(QIcon(":/img/head.jpg"), tr("打开文件(&O)"));
    action_Open->setShortcut(QKeySequence("Ctrl+O"));
    connect(action_Open,&QAction::triggered, this, &MainWindow::on_action_open_triggered);
}

通过代码我们创建了一个编辑菜单,编辑菜单下有打开文件的动作,设置Ctrl+O为快捷键,并为该动作创建槽函数,然后连结这个槽函数。

void MainWindow::on_action_open_triggered()
{
    qDebug() << "打开文件..." << endl;
}

所以每次点击打开文件后输出上面的日志。除了可以为菜单栏添加动作外,还可以添加动作组

    //建立动作组
    QActionGroup * group = new QActionGroup(this);
    QAction * action_L = group->addAction(tr("左对(&L)"));
    action_L->setCheckable(true);
    QAction * action_R = group->addAction(tr("右对(&R)"));
    action_R->setCheckable(true);
    QAction * action_C = group->addAction(tr("居中(&C)"));
    action_C->setCheckable(true);
    editMenu->addSeparator();
    editMenu->addAction(action_L);
    editMenu->addAction(action_R);
    editMenu->addAction(action_C);

我们也可以自定义动作类,我们接下来自定义一个动作类,动作类包含一个label和lineEdit。自定义的动作类叫MyAction,
声明如下

#ifndef MYACTION_H
#define MYACTION_H

#include <QWidgetAction>
#include <QLineEdit>
#include <QObject>
class MyAction : public QWidgetAction
{
    Q_OBJECT
signals:
    void getText(const QString& string);

public:

     explicit MyAction(QObject * parent = 0);
    virtual ~MyAction();
protected:

    virtual QWidget *createWidget(QWidget *parent);

private slots:
    void sentText();
private:
    //声明行编辑器对象
    QLineEdit* lineEdit;
};

#endif // MYACTION_H

createWidget 为一个虚函数,继承自QWidgetAction, 将Action加入菜单或者工具栏就会调用createWidget函数。接下来我们实现这个类

#include "myaction.h"
#include <QSplitter>
#include <QLabel>


MyAction::MyAction(QObject * parent):QWidgetAction(parent){
    // 创建行编辑器
    lineEdit = new QLineEdit;
    // 将行编辑器的按下回车键信号和发送文本槽关联
    connect(lineEdit, &QLineEdit::returnPressed, this, &MyAction::sentText);
}

QWidget* MyAction::createWidget(QWidget * parent){
    if(parent->inherits("QMenu")|| parent->inherits("QToolBar")){
        QSplitter * spliter = new QSplitter(parent);
        QLabel * label = new QLabel;
        label->setText(tr("插入文本:"));
        spliter->addWidget(label);
        spliter->addWidget(lineEdit);
        return spliter;
    }
    return 0;
}

void MyAction::sentText()
{
    emit getText(lineEdit->text());
    lineEdit->clear();
}

构造函数里创建了一个LineEdit,然后绑定了LineEdit的返回信号,在sentText槽函数里发送了getText信号,然后清除了lineEdit里的内容。createWidget里判断了父节点如果是QMenu或者QToolBar,就创建一个spliter,然后将label和lineedit都加入spliter。在mainwindow的构造函数中创建MyAction,并且加入菜单里。然后将MyAction的getText的信号和MainWindow的setText函数绑定在一起。

    MyAction * action = new MyAction(this);
    editMenu->addAction(action);
    connect(action, &MyAction::getText, this, &MainWindow::setText);

MainWindow的槽函数实现如下

void MainWindow::setText(const QString &string){
    ui->textEdit->setText(string);
}

这样当我们点击编辑菜单弹出我们自己实现的MyAction动作,在输入框里输入文字按下回车后文字就会显示到dockwidget的textedit中。
https://cdn.llfc.club/1665062815744.jpg

工具栏

工具栏相比菜单栏更容易操作,更加直观,添加方式和菜单的方式类似,可以添加label,按钮,以及spinbox等。
可以通过ui添加,也可以通过代码添加,下面用代码添加工具栏菜单。

    //工具栏添加元素
    QToolButton * toolBtn = new QToolButton(this);
    toolBtn->setText(tr("颜色"));
    QMenu* colorMenu = new QMenu(this);
    colorMenu->addAction(tr("红色"));
    colorMenu->addAction(tr("绿色"));
    toolBtn->setMenu(colorMenu);
    toolBtn->setPopupMode(QToolButton::MenuButtonPopup);
    ui->toolBar->addWidget(toolBtn);
    QSpinBox* spinBox = new QSpinBox(this);
    ui->toolBar->addSeparator();
    ui->toolBar->addWidget(spinBox);

状态栏

状态栏在窗口的下方,一般在右下方,左下方的为临时的,右下方的为永久的。

void MainWindow::init_status_bar(){
    //显示临时消息
    ui->statusbar->showMessage(tr("欢迎使用多文档编辑器"),2000);
    //创建标签
    QLabel* permanent = new QLabel(this);
    permanent->setFrameStyle(QFrame::Box | QFrame::Sunken);
    permanent->setText("llfc.club");
    ui->statusbar->addPermanentWidget(permanent);
}

总结

源码链接https://gitee.com/secondtonone1/qt-learning-notes

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/683978.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI大底座核心平台:百度百舸AI异构计算平台(AI IaaS)与AI中台(AI PaaS)

AI大底座正是整合了以上端到端全要素技术能力&#xff0c;将基础架构IaaS与应用平台PaaS能力深度融合&#xff0c;面向企业和产业AI生 产与应用的全生命周期提供完整解决方案。 百舸AI异构计算平台是AI IaaS层的核心平台&#xff0c;包括AI计算、AI存储、AI加速、AI容器四层套件…

算法人生(19): 从“LangChain的六大组件”看“个人职业规划”

我们今天要说说和大模型有着密切关系的Langchain &#xff0c;它提供了一个平台&#xff0c;让开发者可以更加轻松地训练、部署和管理这些大模型。具体来说&#xff0c;Langchain 可以通过提供高性能的计算资源、灵活的模型管理和部署选项、以及丰富的监控和调试功能&#xff0…

「动态规划」如何求下降路径最小和?

931. 下降路径最小和https://leetcode.cn/problems/minimum-falling-path-sum/description/ 给你一个n x n的方形整数数组matrix&#xff0c;请你找出并返回通过matrix的下降路径的最小和。下降路径可以从第一行中的任何元素开始&#xff0c;并从每一行中选择一个元素。在下一…

CentOS 环境下 PostgreSQL 在线安装和源码安装详解

1、内容概述 昨天给大家简单的介绍了一下 PostgreSQL,并且在Windows系统上通过图形化界面的方式搭建好了环境&#xff0c;今天我们就来学习一下如何在Linux 系统上搭建 PostgreSQL环境&#xff0c;我会给大家介绍在线安装、离线源码安装以及Docker 安装三种方式。 2、在线安装…

umijs 服务端渲染(SSR) 指南

umijs 服务端渲染&#xff08;SSR&#xff09; 指南 Umi 是什么&#xff1f; Umi&#xff0c;中文可发音为乌米&#xff0c;是可扩展的企业级前端应用框架。Umi 以路由为基础的&#xff0c;同时支持配置式路由和约定式路由&#xff0c;保证路由的功能完备&#xff0c;并以此进…

枚举(enum)+联合体(union)

枚举联合 一.枚举类型1.枚举类型的声明2.枚举类型的优点3.枚举类型的使用 二.联合体1.联合体类型的声明2.联合体的特点3.相同成员的结构体和联合体对比4.联合体大小的计算5.联合体的练习&#xff08;判断大小端&#xff09;6.联合体节省空间例题 一.枚举类型 1.枚举类型的声明…

安全U盘和普通U盘有什么区别?

安全U盘&#xff08;也称为加密U盘或安全闪存驱动器&#xff09;与普通U盘肯定是有一些区别的&#xff0c;从字面意思上来看&#xff0c;就能看出&#xff0c;安全U盘是能够保护文件数据安全性的&#xff0c;普通U盘没这一些功能的&#xff0c;可随意拷贝文件&#xff0c;不防盗…

Hadoop3:MapReduce源码解读之Mapper阶段的TextInputFormat切片机制(3)

Job那块的断点代码截图省略&#xff0c;直接进入切片逻辑 参考&#xff1a;Hadoop3&#xff1a;MapReduce源码解读之Mapper阶段的Job任务提交流程&#xff08;1&#xff09; 5、TextInputFormat源码解析 类的继承关系 它的内容比较少 重写了两个父类的方法 这里关心一下泛型…

《开源模型食用指南》基于Linux环境快速部署开源模型,更适合中国宝宝的部署教程

今天给大家推荐一个非常适合中国宝宝学习的专属大模型教程&#xff0c;也就是它《开源模型食用指南》&#xff01; 当前百模大战正值火热&#xff0c;开源LLM层出不穷。 如今国内外已经涌现了众多优秀开源LLM&#xff0c;国外如LLaMA、Alpaca&#xff0c;国内如ChatGLM、BaiCh…

【Unity Shader入门精要 第13章】使用深度和法线纹理(一)

1. 原理 深度纹理的本质是一张RenderTexture&#xff0c;只不过其中记录的不是颜色值&#xff0c;而是一个深度值 这些深度值来自于顶点在空间变换后得到的归一化设备坐标&#xff08;NDC&#xff09;的Z值 由于NDC坐标的分量取值范围在[-1, 1]之间&#xff0c;要使颜色值能…

欧盟EDPS发布首份生成式人工智能与数据安全指南解读

6月3日&#xff0c;欧洲数据保护监督机构&#xff08;EDPS&#xff09;在其官网上发布了题为《生成式人工智能与EUDPR》的指南&#xff08;注&#xff1a;EUDPR指的是《欧盟2018/1725号条例》&#xff09;&#xff0c;这是首份适用于欧盟机构的人工智能与数据安全指南。 01 指南…

STM32 SPI驱动读取LSM6DSRTR

提示&#xff1a;通过SPI驱动读取传感器数据 文章目录 前言一、LSM6DSRTR二、配置步骤1.配置SPI2.引入 LSM驱动库3.结果 总结 前言 制作一个倾角传感器&#xff0c;通过SPI读取LSM6DSRTR的加速度数据转换为角度&#xff0c;不用IIC的原因是考虑IIC通讯的协议过于繁琐&#xff…

c# iText使用

引入包 用nuget安装itext和itext.bouncy-castle-adapter包&#xff1a; 创建pdf string path "a.pdf"; PdfWriter writer new PdfWriter(path); PdfDocument pdfDoc new PdfDocument(writer); var docnew Document(pdfDoc); Paragraph p new Paragraph(&quo…

Java装饰器模式,装饰器模式通常通过创建一个接口和一个或多个实现了该接口的类来开始,然后创建装饰器类,这些类也实现了相同的接口

1、定义一个接口Component public interface Component { void operation(); }2、创建一个实现了Component接口的简单类SimpleComponent public class SimpleComponent implements Component { Override public void operation() { System.out.println("SimpleCom…

正大国际期货:什么是主力合约?

一个期货品种&#xff0c;在同一时间段&#xff0c;会上市多个月份的合约&#xff0c; 由于主力合约交易量大&#xff0c;流动性高&#xff0c;一般建议新手交易主力合约。 主力合约通常指交易集中&#xff0c;流动性好的合约 &#xff0c;即在一段时间内交易量和持仓量最大的…

java框架树结构实现(带层级、编码、排序)

1、需求 实现一个影像资料库的功能&#xff0c;用树结构对资料进行分类 2、数据结构 通过id、pid表示父子关系 通过code表示层级关系 通过layer表示层级 通过sort进行排序 3、实体类 package org.jeecg.modules.image.entity;import com.baomidou.mybatisplus.annotation…

交叉编译freetype

目录 一、前言 二、交叉编译 freetype 1.交叉编译安装工具链 zlib 2.交叉编译安装工具链 libpng 3.交叉编译安装工具链 freetype 4.编译测试发现错误并解决 5.上机测试 一、前言 交叉编译常见错误解决方法可看&#xff1a;交叉编译中常见错误解决方法_交叉编译后fail t…

DevExpress Installed

一、What’s Installed 统一安装程序将DevExpress控件和库注册到Visual Studio中&#xff0c;并安装DevExpress实用工具、演示应用程序和IDE插件。 Visual Studio工具箱中的DevExpress控件 Visual Studio中的DevExpress菜单 Demo Applications 演示应用程序 Launch the Demo…

基于细节增强卷积和内容引导注意的单图像去雾

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读&#xff1a;DEA-Net&#xff1a;基于细节增强卷积和内容引导注意的单图像去雾1、研究背景2、方法提出3、相关知识3.1、DEConv3.3、多重卷积的…

Springboot+druid+多数据源

背景&#xff1a;早期项目是springboot2.x druid 的单数据源工程&#xff0c;其中使用了dblink的方式进行跨数据库访问。现在客户的机房搬迁&#xff0c;记账的下游数据库说是搬到不同区域&#xff0c;dblink的方式需要长期占用资源&#xff0c;需要修改成直连方式。 按照AI的…