Advanced Clipboard Handling

Most applications make use of Qt's built-in clipboard handling in one way or another. For example, the QTextEdit class provides support for Ctrl+X, Ctrl+C, and Ctrl+V, along with cut(), copy(), and paste() slots, so little or no additional code is required.

When writing our own classes, we can access the clipboard through QApplication ::clipboard(), which returns a pointer to the application's QClipboard object. Handling the system clipboard is easy: Call setText(), setImage(), or setPixmap() to put data on the clipboard, and text(), image(), or pixmap() to retrieve the data. We have already seen examples of clipboard use in the Spreadsheet application from Chapter 4 and in the Diagram application from Chapter 8.

For some applications, the built-in functionality might not be sufficient. For example, we might want to provide data that isn't just text or an image. Or we might want to provide data in many different formats, for maximum interoperability with other applications. The issue is very similar to what we encountered earlier with drag and drop, and the answer is also similar: We must subclass QMimeSource and reimplement format() and encodedData().

If our application supports drag and drop, we can simply reuse our custom QDragObject subclass and put it on the clipboard using the setData() function. Since QDragObject inherits QMimeSource and the clipboard understand QMimeSources, this works seamlessly.

For example, here's how we could implement the copy() function of a QTable subclass:

void MyTable::copy() { QApplication::clipboard()->setData(dragObject()); }

At the end of the previous section, we implemented dragObject() to return a CellDrag that stores the selected cells' contents.

To retrieve the data, we can call data() on the clipboard. Here's how we could implement the paste() function of a QTable subclass:

void MyTable::paste() { QMimeSource *source = QApplication::clipboard() ->data(); if (CellDrag::canDecode(source)) { QString str; CellDrag::decode(source, str); performPaste(str); } }

The performPaste() is essentially the same as the Spreadsheet::paste() function presented in Chapter 4 (p. 81).

This is all that is required, along with a custom QMimeSource, to add clipboard support for a custom type.

The X11 clipboard provides additional functionality not available on Windows or Mac OS X. On X11, it is usually possible to paste a selection by clicking the middle button of a three-button mouse. This is done using a separate "selection" clipboard. If you want your widgets to support this kind of clipboard as well as the standard one, you must pass QClipboard::Selection as an additional argument to the various clipboard calls. For example, here's how we would reimplement mouseReleaseEvent() in a text editor to support pasting using the middle mouse button:

void MyTextEditor::mouseReleaseEvent(QMouseEvent *event) { QClipboard *clipboard = QApplication::clipboard(); if (event->button() == MidButton && clipboard->supportsSelection()) { QString text = clipboard->text(QClipboard::Selection); pasteText(text); } }

On X11, the supportsSelection() function returns true. On other platforms, it returns false.

Категории