C++学习之路(八)C++ 用Qt5实现一个工具箱(增加一个粘贴板记录管理功能)- 示例代码拆分讲解

news2024/11/15 9:11:19

昨天,我们用 Qt5 实现了一个小工具箱的雏形《C++ 实现简单的Qt界面(消息弹框、按钮点击事件监听)》,但是没什么实用价值。为了增加点作用,我们今天就为这个小工具箱增加第一个小功能 「 粘贴板记录管理功能 」,下面我们就来看看如何来规划开发一个这样的小功能并且添加到我们的工具箱中吧。

先看效果

在这里插入图片描述

功能规划

  • 主窗口:
    • 管理粘贴板记录按钮: 点击后会显示或隐藏剪贴板记录的管理窗口。
  • 剪贴板管理窗口:
    • 剪贴板记录列表: 自动监测剪贴板内容的变化,并将文本记录显示在窗口中。
    • 清空记录按钮: 点击后会清空剪贴板中的文本记录和窗口中显示的文本。

这个程序要展示一个简单的界面,允许用户通过管理窗口监测和清空剪贴板中的文本记录。通过信号槽连接和 Qt 的窗口部件,实现剪贴板内容的监测和用户界面的交互功能。

实现代码

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QDebug>
#include <QListWidget>
#include <QClipboard>
#include <QMimeData>

#define myApp (dynamic_cast<QApplication *>(QCoreApplication::instance()))

class ClipboardManager : public QWidget {
Q_OBJECT
public:
    explicit ClipboardManager(QWidget *parent = nullptr) : QWidget(parent) {
        auto *layout = new QVBoxLayout(this);

        listWidget = new QListWidget(this);
        updateList(); // 初始更新列表

        auto *clearButton = new QPushButton("清空记录", this);
        connect(clearButton, &QPushButton::clicked, this, &ClipboardManager::clearClipboard);

        layout->addWidget(listWidget);
        layout->addWidget(clearButton);

        setLayout(layout);

        connect(myApp->clipboard(), &QClipboard::dataChanged, this, &ClipboardManager::updateList);
    }

private slots:
    void updateList() {
        const QClipboard *clipboard = myApp->clipboard();
        const QMimeData *mimeData = clipboard->mimeData();

        if (mimeData->hasText()) {
            const QString clipboardText = mimeData->text();

            if (!clipboardText.isEmpty()) {
                listWidget->addItem(clipboardText);
            }
        }
    }

    void clearClipboard() {
        myApp->clipboard()->clear();
        listWidget->clear();
    }

private:
    QListWidget *listWidget;
};

class MyMainWindow : public QWidget {
Q_OBJECT
public:
    explicit MyMainWindow(QWidget *parent = nullptr) : QWidget(parent) {
        setWindowTitle("实用功能示例");

        auto *layout = new QVBoxLayout(this);

        auto *button1 = new QPushButton("显示消息框");
        connect(button1, &QPushButton::clicked, this, &MyMainWindow::showMessageBox);

        auto *button2 = new QPushButton("执行特定操作");
        connect(button2, &QPushButton::clicked, this, &MyMainWindow::performSpecificAction);

        auto *clipboardButton = new QPushButton("管理粘贴板记录");
        connect(clipboardButton, &QPushButton::clicked, this, &MyMainWindow::toggleClipboardManager);

        layout->addWidget(button1);
        layout->addWidget(button2);

        clipboardManager = new ClipboardManager(this);
        clipboardManager->hide();
        layout->addWidget(clipboardManager);

        layout->addWidget(clipboardButton);

        setLayout(layout);
    }

private slots:
    void showMessageBox() {
        QMessageBox::information(this, "消息", "这是一个消息框示例!");
    }

    static void performSpecificAction() {
        // 执行特定的操作
        qDebug() << "执行了特定操作!";
    }

    void toggleClipboardManager() {
        if (clipboardManager->isHidden()) {
            clipboardManager->show();
        } else {
            clipboardManager->hide();
        }
    }

private:
    ClipboardManager *clipboardManager;
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    MyMainWindow mainWindow;
    mainWindow.show();

    return QApplication::exec();
}

#include "main.moc"

代码逐步讲解及知识点介绍

让我们逐步分解和讲解这个示例,同时列出涉及的知识点。

1. 包含的头文件和宏定义

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QDebug>
#include <QListWidget>
#include <QClipboard>
#include <QMimeData>
  • QApplication Qt 的应用程序类,管理应用程序的主要设置和行为。
  • QWidget Qt 的窗口部件基类,提供了窗口的功能和特性。
  • QPushButton Qt 的按钮部件类,用于创建按钮。
  • QVBoxLayout Qt 的垂直布局管理器类,用于管理窗口部件的垂直布局。
  • QMessageBox Qt 的消息框部件类,用于显示消息和提示。
  • QDebug Qt 的调试输出类,用于输出调试信息。
  • QListWidget Qt 的列表部件类,用于显示项目列表。
  • QClipboard Qt 的剪贴板类,用于访问和管理系统剪贴板。
  • QMimeData Qt 的多用途数据容器类,用于在剪贴板中保存数据。
#define myApp (dynamic_cast<QApplication *>(QCoreApplication::instance()))
  • myApp 宏定义: 这个宏定义用于获取当前应用程序的指针,并将其转换为 QApplication* 类型。它通过 QCoreApplication::instance() 获取应用程序对象的指针,然后通过 dynamic_cast 进行类型转换。这样,myApp 宏可以在程序中轻松访问当前应用程序的对象。(其实主要是为了不让 Clion 提示 Clang-Tidy: Do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead 这个警告 o(╥﹏╥)o 拯救强迫症 ~ )

2. ClipboardManager

ClipboardManager 类是我们用于管理剪贴板内容的窗口部件。它主要负责监测剪贴板中的文本内容变化,并将这些文本记录显示在一个列表中。同时,它也提供了清空剪贴板内容的功能。

class ClipboardManager : public QWidget {
    Q_OBJECT
public:
    explicit ClipboardManager(QWidget *parent = nullptr) : QWidget(parent) {
        // 构造函数:初始化剪贴板记录管理窗口
        // 创建布局和窗口部件,并连接剪贴板数据变化信号到槽函数
    }

private slots:
    void updateList() {
        // 槽函数:更新剪贴板记录列表
        // 从剪贴板获取文本,并显示在列表部件中
    }

    void clearClipboard() {
        // 槽函数:清空剪贴板和记录列表
        // 清空剪贴板内容,并清空列表部件中显示的内容
    }

private:
    QListWidget *listWidget;
};

知识点:

  • 继承与构造函数: 继承自 QWidget 类,并在构造函数中初始化剪贴板记录管理窗口。

  • 布局和窗口部件: 使用 QVBoxLayout 布局和 QListWidget 列表部件。

    QVBoxLayout 是 Qt 框架中的一个布局管理器类,用于在窗口中垂直地排列窗口部件(Widgets)。
    QListWidget 是 Qt 框架中用于显示项目列表的部件类。它可以用来展示项目的列表,每个项目可以包含文本、图标等信息。QListWidget 提供了一些方法来方便地管理项目列表,比如添加、删除、清空项目等。它还支持各种信号,可以在项目被选中、双击、拖动等操作时发出相应的信号,方便对用户交互做出响应。

  • 信号槽连接: 通过 connect 将剪贴板数据变化信号连接到槽函数 updateList

  • 剪贴板操作: 使用 QClipboardQMimeData 读取和管理剪贴板的文本内容。

3. MyMainWindow

class MyMainWindow : public QWidget {
    Q_OBJECT
public:
    explicit MyMainWindow(QWidget *parent = nullptr) : QWidget(parent) {
        // 构造函数:初始化主窗口,包含按钮和剪贴板管理窗口
        // 创建按钮,并连接点击事件到对应的槽函数
    }

private slots:
    void showMessageBox() {
        // 槽函数:显示消息框
        // 显示一个简单的消息框
    }

    static void performSpecificAction() {
        // 静态槽函数:执行特定操作
        // 输出一条特定的消息到控制台
    }

    void toggleClipboardManager() {
        // 槽函数:显示或隐藏剪贴板管理窗口
        // 控制剪贴板管理窗口的显示或隐藏状态
    }

private:
    ClipboardManager *clipboardManager;
};

知识点:

  • 构造函数: 初始化主窗口,包含按钮和剪贴板管理窗口。
  • 按钮和事件连接: 创建按钮,并通过 connect 将点击事件连接到相应的槽函数。
  • 消息框显示: 使用 QMessageBox::information 显示简单的消息框。
  • 静态函数: 一个静态成员函数 performSpecificAction,在按钮点击时输出消息到控制台。

4. main() 函数

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    MyMainWindow mainWindow;
    mainWindow.show();

    return QApplication::exec();
}

知识点:

  • 应用程序对象: 创建 QApplication 对象,是 Qt 应用程序的入口点。
  • 主窗口显示: 实例化主窗口并显示。

总结涉及的知识点:

  • Qt 窗口部件: QWidget、QPushButton、QVBoxLayout、QListWidget。
  • 信号槽机制: connect 函数连接按钮点击事件和剪贴板数据变化信号到槽函数。
  • 剪贴板操作: QClipboard 和 QMimeData 读取和管理剪贴板的文本内容。
  • 静态函数和槽函数: 包括静态函数和普通槽函数的定义和使用。
  • 应用程序对象获取和宏定义: 获取当前应用程序的指针,并使用宏定义简化代码。

本示例中,我们要注意哪些地方呢?

在这个示例中,有几个关键点值得注意:

  1. 信号与槽连接: 这个示例通过 connect 函数将信号与槽函数连接起来,实现了按钮点击和剪贴板数据变化时的响应操作。需要注意信号和槽函数的参数类型和匹配,确保连接正确。

  2. 动态创建部件: 示例中使用 new 关键字动态创建了窗口部件(如 QPushButtonQListWidget 等),并将它们添加到布局中。确保这些动态创建的部件在适当的时候被正确释放,以避免内存泄漏。

  3. 静态槽函数: 示例中有一个静态成员函数 performSpecificAction 作为槽函数。需要注意静态成员函数的特殊性,它没有访问实例变量的权限,只能访问静态成员变量或全局变量。

  4. 剪贴板操作: 对剪贴板的操作需要小心,特别是在清空剪贴板内容时,确保用户明确的操作意图,以免误操作造成数据丢失。

  5. 布局管理: 布局的设计需要考虑界面的美观性和用户体验。在添加新的功能或部件时,要考虑布局的合理性,避免窗口部件重叠或过于拥挤。

综上所述,在编写和修改代码时,要特别注意这些关键点,以确保程序的稳定性、可靠性和用户友好性。


本文就到这里了,感谢您的阅读,明天还有更多的实例学习文章等着你 🎆。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何正确选择爬虫采集接口和API?区别在哪里?

在信息时代&#xff0c;数据已经成为了一个国家、一个企业、一个个人最宝贵的资源。而爬虫采集接口则是获取这些数据的重要手段之一。本文将从以下八个方面进行详细讨论&#xff1a; 1.什么是爬虫采集接口&#xff1f; 2.爬虫采集接口的作用和意义是什么&#xff1f; 3.爬虫…

数据可视化:在Jupyter中使用Matplotlib绘制常用图表

Matplotlib是一个强大的数据可视化库&#xff0c;用于创建各种图表。 在Jupyter中使用Matplotlib可以轻松实现折线图、柱状图、散点图和饼图等常用图表。 本篇文章将为你详细讲解用matlpotlib绘制常用图表的方法。 1、折线图 折线图是展示数据趋势和变化的常见图表类型。 …

【Proteus仿真】【51单片机】智能晾衣架设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用LCD1604液晶、按键、蜂鸣器、L298N电机、PCF8591 ADC模块、DHT11温湿度传感器、雨滴传感器、风速、光线传感器等。 主要功能&#xff1a; 系统运行…

负公差智能测径仪 升级体验智能仪器

负公差轧制离不开智能测径仪 受自动化控制程度限制&#xff0c;一些工艺流程的操作还是依靠工人经验来完成&#xff0c;由于个人工作技能水平限制&#xff0c;尺寸控制极不稳定&#xff0c;因此控制台就需要及时准确的了解成品钢的尺寸及重量。现在信息的沟通主要依靠电话。取样…

excel合并单元格教程

在表格里&#xff0c;总是会遇到一级表格、二级表格的区别&#xff0c;这时候一级表格会需要合并成一个大格子&#xff0c;那么excel如何合并单元格呢&#xff0c;其实使用快捷键或者功能键就可以了。 excel如何合并单元格&#xff1a; 1、首先我们用鼠标选中所有要合并的单元…

geemap学习笔记015:下载哨兵2号(Sentinel-2)数据

前言 使用GEE下载数据应该是最常见的功能了&#xff0c;今天就介绍一下如何使用geemap下载哨兵2号(Sentinel-2)数据&#xff0c;分别包括自己画感兴趣&#xff0c;以及利用Assets中的shp文件进行下载。 1 自己画感兴趣下载哨兵2号影像 import geemap import eeMap geemap.M…

北美区域性确定性预测系统平均温度数据

区域确定性预测系统&#xff08;RDPS&#xff09; 区域确定性预测系统 (RDPS) 进行物理计算&#xff0c;以 10.0 公里网格&#xff08;1/11 度&#xff09;空间分辨率对当天到未来 48 小时内的大气元素进行确定性预测。平均温度数据覆盖北美&#xff0c;由加拿大气象局 (MSC) …

Python语言学习笔记之四(Python文档化)

本课程对于有其它语言基础的开发人员可以参考和学习&#xff0c;同时也是记录下来&#xff0c;为个人学习使用&#xff0c;文档中有此不当之处&#xff0c;请谅解。 Python文档化是指在Python代码中添加注释和文档字符串&#xff0c;以提供有关代码的详细信息和说明。 文档的…

最简单的英文网站

代码图&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>College Job Website</title> <link rel"stylesheet" href"https://cdn.staticfile.org/…

java学习part17final

110-面向对象(高级)-关键字final的使用及真题_哔哩哔哩_bilibili 1.概念 tips&#xff1a;java里有const关键字&#xff0c;但是用于保留字&#xff0c;不会使用&#xff0c;目前没有意义。 final变量没有默认赋值&#xff0c;只能在以下三个地方赋值&#xff0c;且只能赋值一…

数据结构_D6(231126)

①二分折半查找 ②单排快排主调

20231128让RK3399的挖掘机开发板在Andorid12系统下永不休眠

20231128让RK3399的挖掘机开发板在Andorid12系统下永不休眠 2023/11/28 7:56 适用于SOC以及系统版本&#xff1a; RK3399&#xff1a;Android10/11/12 RK3568&#xff1a;Android11/12 RK3588&#xff1a;Android12 缘起&#xff0c;调试的时候&#xff0c;RK3399的挖掘机开发板…

vue3+ts 指令拖拽案例

<template><div class"box" v-move><div class"header"></div><div>内容</div></div> </template><script setup lang"ts"> import { ref, Directive, DirectiveBinding } from "vu…

PLC与组态王之间Modbus无线通讯的从站设置

本方案主要详述了在多台西门子300PLC与组态王之间Modbus无线通讯中如何设置从站。方案中所用到的无线通讯终端是DTD434MC——欧美系PLC专用无线通讯终端。 一、方案概述 无线Modbus网络组成如下&#xff1a; 二、测试背景 ● PC端组态软件版本&#xff1a;组态王6.55 ● 默…

京东秒杀之秒杀详情

1 编写前端页面&#xff08;商品详情&#xff09; <!DOCTYPE html> <head><title>商品详情</title><meta http-equiv"Content-Type" content"text/html; charsetUTF-8" /><script type"text/javascript" src&…

HTML页面开发

html简单页面开发&#xff0c;主要用来测试 1. 开发环境&#xff1a;VScode 1. 在某路径下先新建文件夹&#xff0c;打开VScode打开文件夹&#xff0c;新建文件&#xff0c;文件命名为index.html 2. 安装库 open in browser 库安装完成后&#xff0c;在编写文本位置右击->op…

RK3568 android11 实现双路I2C触摸 --gt9xx

一&#xff0c;GT911 触摸屏简介 它的接口类型为 I2C &#xff0c;供电电压和通讯电压均为 3.3V 。这款电容触摸屏内置了上拉电阻&#xff0c;这意味着我们的开发板上与该触摸屏的接口处不需要设置上拉电阻。关于线序&#xff0c;同样是 GT911 &#xff0c;不同批次的器件都有…

【JMeter】配置元件

1. 元件的分类 HTTP Request Default 作用&#xff1a; 可以配置成通用的信息&#xff0c;可复用 ​​​​​​​ JDBC Connection Configuration 作用&#xff1a;连接数据库 前提&#xff1a; 下载好对应数据类型的jar包 ​​​​​​​ HTTP Header Manager信息头管理…

Scanner常用知识点

在Java中&#xff0c;Scanner类是用于读取用户输入的工具类&#xff0c;可以从多种输入源读取数据&#xff0c;如标准输入流、文件或字符串。以下是一些Scanner类的常用知识点&#xff1a; Scanner的初始化&#xff1a;在使用Scanner类之前&#xff0c;需要先将其导入到你的Ja…

基于SSM的零食物语购物商城的设计与实现

基于SSM的零食物语购物商城的设计与实现 摘要&#xff1a;“日常网购”作为一种比传统购物更便捷的方式&#xff0c;越来越受到大众的欢迎和认可。因此&#xff0c;系统的设计和应用技术对零食购物商城网站的要求越来越高&#xff0c;于是本系统应运而生。基于SSM[1]的零食购物…