剪贴板是个啥就不用多介绍了,最直观的功能是实现应用程序之间数据共享。就是咱们常说的“复制”、“粘贴”功能。
在 Qt 中,QClipboard 类提供了相关 API 让应用程序具备读/写剪贴板的能力。数据通过 QMimeData 类包装。该类使用 MIME 类型来标识数据。比如,要包装的数据是纯文本内容,就使用 text/plain;如果是 PNG 图像数据,就用 image/png。当然,自定义类型也是可以的,如 application/xxx。
QMimeData 的核心方法是 setData 和 data。setData 方法用来放入数据,data 方法用来取出数据。setData 方法的签名如下:
void setData(const QString &mimetype, const QByteArray &data);
mimetype 参数为字符串,指定数据的 MIME 类型;data 参数就是数据本尊,类型为字节序列。通过 setData 方法的签名,咱们也能知道,QMimeData 类可以放任意内容。要获取数据时,data 方法需要通过 MIME 类型来检索。
为了便于存取常见的数据——如文本、图像、HTML文本等,QMimeData 类提供一些封装好的方法成员:
文本 | setText | 设置普通文本 |
text | 获取普通文本 | |
hasText
|
判断是否存在文本数据 | |
HTML文本 |
setHtml
|
设置 HTML 文本 |
html
|
获取HTML文本 | |
hasHtml
|
判断是否存在 HTML 文本数据 | |
URL |
setUrls
|
设置 URL 列表,参数为 QList<QUrl> |
urls | 获取 URL 列表 | |
hasUrls
|
检测是否存在 URL 列表 | |
图像 |
setImageData
|
设置图像数据 |
imageData
|
获取图像数据 | |
hasImage
|
判断是否存在图像数据 | |
颜色 |
setColorData
|
设置颜色数据 |
colorData
|
获取颜色数据 | |
hasColor
|
是否存在颜色数据 |
QClipboard 类不能直接实例化使用,它由 QGuiApplication 类的静态成员 clipboard 公开。该静态成员返回 QClipboard 类的指针,程序代码将通过这个指针来访问 QClipboard 对象。由于 QApplication 类派生自 QGuiApplication,当然也继承了 clipboard 成员。
下面做一个简单的练习:复制和粘贴文本。
MyWindow 类的头文件。
class MyWindow : public QWidget { Q_OBJECT public: MyWindow(QWidget* parent = nullptr); ~MyWindow(); private: void _initUi(); // 私有方法 // 下面是私有字段 QLineEdit* _txtInput; QLabel* _lbTxt; QPushButton* _btnCopy; QPushButton* _btnPaste; // 用来布局控件的 QGridLayout* _layout; // 下面成员响应 clicked 信号 void onCopy(); void onPaste(); };
_initUi 方法负责初始化窗口上的东西。这个窗口有四个组件:一个 QLineEdit 用来输入文本;一个 QLabel 用来显示文本;然后是两个按钮—— 执行“复制”和“粘贴”操作。
后面两个方法 onCopy 和 onPaste 分别与两个按钮的 clicked 信号绑定。
构造函数的实现比较简单,就是调用 _initUi 方法。
MyWindow::MyWindow(QWidget* parent) : QWidget::QWidget(parent) { // 初始化UI this -> _initUi(); } MyWindow::~MyWindow() { }
析构函数这里啥也不做。
下面是 _intUi 的实现代码。
void MyWindow::_initUi() { // 设置一下窗口 this->setWindowTitle("复制粘贴文本"); this->setGeometry(560, 480, 320, 150); this->setMinimumSize(300, 150); _txtInput = new QLineEdit(); _lbTxt = new QLabel(); _btnCopy = new QPushButton("复制"); _btnPaste = new QPushButton("粘贴"); _layout = new QGridLayout(this); // 设置空白 _layout->setSpacing(12); // 放置各控件 _layout->addWidget(_txtInput, 0, 0); _layout->addWidget(_btnCopy, 1, 0); _layout->addWidget(_lbTxt, 0, 2); _layout->addWidget(_btnPaste, 1, 2); _layout->setColumnStretch(0, 2); _layout->setColumnStretch(1, 1); _layout->setColumnStretch(2, 2); // 绑定信号和槽 connect(_btnCopy, &QPushButton::clicked, this, &MyWindow::onCopy); connect(_btnPaste, &QPushButton::clicked, this, &MyWindow::onPaste); }
QGridLayout 类也是一个组件,以网格方式布局各组件。网格的行和列是自动划分的。上面代码中其实用到了三列两行:
1、QLineEdit 在第一列第一行;
2、第二列空着,没放东西;
3、 QLabel 组件在第三列第一行;
4、“复制”按钮在第一列第二行;
5、“粘贴”按钮在第二行第二行。
这三行是设定空间比例的。
_layout->setColumnStretch(0, 2); _layout->setColumnStretch(1, 1); _layout->setColumnStretch(2, 2);
这意思就是,列的总宽平均分为4份,第一列和第三列都占两份,第二列只占一份。
随后是与 clicked 信号绑定的两个私有方法。
void MyWindow::onCopy() { // 获得 QClipboard 的引用 QClipboard* clboard = QApplication::clipboard(); // 设置文本数据 clboard -> setText(_txtInput -> text()); } void MyWindow::onPaste() { //