昨天,我们用 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
。 -
剪贴板操作: 使用
QClipboard
和QMimeData
读取和管理剪贴板的文本内容。
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 读取和管理剪贴板的文本内容。
- 静态函数和槽函数: 包括静态函数和普通槽函数的定义和使用。
- 应用程序对象获取和宏定义: 获取当前应用程序的指针,并使用宏定义简化代码。
本示例中,我们要注意哪些地方呢?
在这个示例中,有几个关键点值得注意:
-
信号与槽连接: 这个示例通过
connect
函数将信号与槽函数连接起来,实现了按钮点击和剪贴板数据变化时的响应操作。需要注意信号和槽函数的参数类型和匹配,确保连接正确。 -
动态创建部件: 示例中使用
new
关键字动态创建了窗口部件(如QPushButton
、QListWidget
等),并将它们添加到布局中。确保这些动态创建的部件在适当的时候被正确释放,以避免内存泄漏。 -
静态槽函数: 示例中有一个静态成员函数
performSpecificAction
作为槽函数。需要注意静态成员函数的特殊性,它没有访问实例变量的权限,只能访问静态成员变量或全局变量。 -
剪贴板操作: 对剪贴板的操作需要小心,特别是在清空剪贴板内容时,确保用户明确的操作意图,以免误操作造成数据丢失。
-
布局管理: 布局的设计需要考虑界面的美观性和用户体验。在添加新的功能或部件时,要考虑布局的合理性,避免窗口部件重叠或过于拥挤。
综上所述,在编写和修改代码时,要特别注意这些关键点,以确保程序的稳定性、可靠性和用户友好性。
本文就到这里了,感谢您的阅读,明天还有更多的实例学习文章等着你 🎆。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇。