IT Notes

QClipboard: Использование буфера обмена в Qt

Возникают ситуации, когда в приложении необходимо реализовать прямой доступ к буферу обмена. Это может потребоваться в программах с особой логикой операций копирования-вставки, или во вспомогательных утилитах, увеличивающих эффективность и простоту работы на компьютере.

В Qt для взаимодействия с буфером обмена удобно использовать класс QClipboard. Он позволяет отслеживать изменения в буфере обмена и добавлять в него произвольную информацию.

Разработаем простое приложение, которое формирует список строк текста, добавленных в буфер обмена за время его работы. А затем позволяет по двойному клику перенести нужный текст из списка в буфер обмена:

qclipboard-demo-sample

Заголовочный файл mainwidget.h:

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>

class QModelIndex;

namespace Ui {
class MainWidget;
}

class MainWidget : public QWidget {
    Q_OBJECT

public:
    explicit MainWidget( QWidget* parent = 0 );
    ~MainWidget();

private slots:
    void onClipboardChanged();
    void onListDbClicked( const QModelIndex& index );

private:
    Ui::MainWidget* ui;
};

#endif // MAINWIDGET_H

Здесь лишь обратим внимание на заготовки двух слотов: onClipboardChanged() - обработчик сигнала, когда в буфер обмена что-либо добавляется; и onListDbClicked() - обработчик сигнала двойного клика на строке списка QListWidget.

Реализация mainwidget.cpp:

#include "mainwidget.h"
#include "ui_mainwidget.h"

#include <QClipboard>
#include <QMimeData>
#include <QDebug>

MainWidget::MainWidget( QWidget* parent ) :
    QWidget( parent ),
    ui( new Ui::MainWidget ) {
    ui->setupUi( this );

    if( QClipboard* c = QApplication::clipboard() ) {
        connect( c, SIGNAL( dataChanged() ), SLOT( onClipboardChanged() ) );
    }

    connect( ui->lstHistory, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onListDbClicked( QModelIndex ) ) );
}

MainWidget::~MainWidget() {
    delete ui;
}

void MainWidget::onClipboardChanged() {
    if( QClipboard* c = QApplication::clipboard() ) {
        if( const QMimeData* m = c->mimeData() ) {
            if( m->hasText() ) {
                ui->lstHistory->insertItem( 0, m->text() );
            }
        }
    }
}

void MainWidget::onListDbClicked( const QModelIndex& index ) {
    const QString& text = ui->lstHistory->item( index.row() )->text();
    if( QClipboard* c = QApplication::clipboard() ) {
        c->disconnect( this );
        c->setText( text );
        connect( c, SIGNAL( dataChanged() ), SLOT( onClipboardChanged() ) );
    }
}

Получить экземпляр QClipboard мы можем от класса приложения:

QClipboard* c = QApplication::clipboard();

Чтобы получать уведомления об изменениях в буфере обмена, связываем сигнал dataChanged() с заранее заготовленным обработчиком onClipboardChanged().

Логика чтения содержимого буфера обмена строится на QMimeData. Ранее мы уже сталкивались с этим классом, когда говорили о Drag&Drop в Qt.

Вставка в буфер обмена с помощью QClipboard интуитивно понятна и похожа на этап Drag в процедуре Drag&Drop. Заметим, что перед добавлением строки в буфер обмена мы отключаем обработчик сигнала dataChanged(), а после подключаем его вновь:

void MainWidget::onListDbClicked( const QModelIndex& index ) {
    const QString& text = ui->lstHistory->item( index.row() )->text();
    if( QClipboard* c = QApplication::clipboard() ) {
        c->disconnect( this );
        c->setText( text );
        connect( c, SIGNAL( dataChanged() ), SLOT( onClipboardChanged() ) );
    }
}

Если бы мы этого не делали, то наше приложение фиксировало изменения в буфере обмена, которые само и спровоцировало.

Исходники

 Скачать пример работы с буфером обмена в Qt с помощью QClipboard

Понравилась статья?
Не забудь поделиться ей с друзьями!

Похожие публикации

Комментарии

хотелось бы увидеть как сделать тоже самое для MacOS, так как dataChanged() там не работает.

> On macOS and with Qt version 4.3 or higher, clipboard changes made by other applications will only be detected when the application is activated.

Anonymous:

хотелось бы увидеть как сделать тоже самое для MacOS, так как dataChanged() там не работает.

> On macOS and with Qt version 4.3 or higher, clipboard changes made by other applications will only be detected when the application is activated.

Здравствуйте. К сожалению, у меня нет возможности тестирования под Mac OS X. Однако в документации упоминается сигнал QClipboard::changed(QClipboard::Mode mode), для которого соответствующее ограничение не упоминается. С другой стороны, я допускаю, что это лишь неточность или просто неоднозначность в документации, поэтому без проверки выводы делать не могу.

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

RSS RSS-рассылка

Популярное

Дешевый хостинг