9-2 support orting DRAM drag types)

Source: Internet
Author: User

In the example in the previous section, we use the class qmimedata to represent the normal MIME type. Call qmimedata: settext () to drag the text and call qmimedata: URLs () to obtain the URL text list. You can use the qmimedata class to drag common text, HTML text, image, URLs, and color. However, if we need to drag the custom type, we need to use the following method: 1. use qbytearray to represent arbitrary data. Call the qmimedata: setdata () function to obtain data through qmimedata: Data. 2. Define the qmimedata subclass and re-implement the formats () and retrievedata () functions to process custom data types .. 3. Define the qmimedata subclass to hold any data types that only occur within an application. The first method does not need to inherit classes, but it has some disadvantages: even if it is not accepted, we also need to convert the data type to qbytearray, if we want to provide MIME types that can interact with a large number of applications, we need to save the interactive data in multiple copies (one copy for each MIME type ). If the interaction data volume is large, the execution speed of the program will surely slow down. The second and third methods can avoid or minimize these problems. We use an example to describe these methods, so that the qtablewidget control supports drag-and-drop. The data types that can be dragged are: text/plain, text/html, text/CSV. The first method is implemented as follows:
void MyTableWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        int distance = (event->pos() - startPos).manhattanLength();
        if (distance >= QApplication::startDragDistance())
            startDrag();
    }
    QTableWidget::mouseMoveEvent(event);
}
void MyTableWidget::startDrag()
{
    QString plainText = selectionAsPlainText();
    if (plainText.isEmpty())
        return;
    QMimeData *mimeData = new QMimeData;
    mimeData->setText(plainText);
    mimeData->setHtml(toHtml(plainText));
    mimeData->setData("text/csv", toCsv(plainText).toUtf8());
    QDrag *drag = new QDrag(this);
    drag->setMimeData(mimeData);
    if (drag->start(Qt::CopyAction | Qt::MoveAction) == Qt::MoveAction)
        deleteSelection();
}
Call startdrag () in the mousemoveevent () function to start dragging. We call the settext () function, sethtml () function to set the MIME type to text/plain, text/HTML data, the function setdata () to save text/CSV data, setdata () save any MIME data type as a qbytearray data. The implementation of the selectionasstring () function is similar to Spreadsheet: Copy () in Chapter 4.
 
QString MyTableWidget::toCsv(const QString &plainText)
{
    QString result = plainText;
    result.replace("//", "////");
    result.replace("/"", "///"");
    result.replace("/t", "/", /"");
    result.replace("/n", "/"/n/"");
    result.prepend("/"");
    result.append("/"");
    return result;
}
QString MyTableWidget::toHtml(const QString &plainText)
{
    QString result = Qt::escape(plainText);
    result.replace("/t", "<td>");
 
    result.replace("/n", "/n<tr><td>");
    result.prepend("<table>/n<tr><td>");
    result.append("/n</table>");
    return result;
}
The tocsv () and tohtml () functions convert tabs and newlines to vcsv characters (using commas to separate data) or HTML characters. For example
Red     Green     Blue
Cyan    Yellow    Magenta
Convert to (CSV ):
"Red", "Green", "Blue"
"Cyan", "Yellow", "Magenta"
Or (HTML)
<table>
<tr><td>Red<td>Green<td>Blue
<tr><td>Cyan<td>Yellow<td>Magenta
</table>
Use the qstring: Replace () function to make the conversion as simple as possible. Function QT: escape () is used to explain special characters in HTML.
void MyTableWidget::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasFormat("text/csv")) {
        QByteArray csvData = event->mimeData()->data("text/csv");
        QString csvText = QString::fromUtf8(csvData);
        ...
        event->acceptProposedAction();
    } else if (event->mimeData()->hasFormat("text/plain")) {
        QString plainText = event->mimeData()->text();
        ...
        event->acceptProposedAction();
    }
}
Although we provide three different data formats, we only accept two of them in dropevent. If you drag a string of HTML characters from a grid of qtablewidget to an HTML compiler, convert the data in the grid to HTML. If you drag an HTML to the qtablewidget control, we do not want to accept it. To smoothly implement this example, you must call setacceptdrops (true) and setselectionmode (contiguousselection) in the mytablewidget constructor ). Now let's implement this example again. This time, we use qminedata as the base class, and use the qminedata subclass to implement data conversion, avoiding conversion between qtablewidgetitem and qbytearray. The following is a subclass definition:
class TableMimeData : public QMimeData
{
    Q_OBJECT
public:
    TableMimeData(const QTableWidget *tableWidget,
                  const QTableWidgetSelectionRange &range);
    const QTableWidget *tableWidget() const { return myTableWidget; }
    QTableWidgetSelectionRange range() const { return myRange; }
    QStringList formats() const;
protected:
    QVariant retrieveData(const QString &format,
                          QVariant::Type preferredType) const;
private:
    static QString toHtml(const QString &plainText);
    static QString toCsv(const QString &plainText);
    QString text(int row, int column) const;
    QString rangeAsPlainText() const;
    const QTableWidget *myTableWidget;
    QTableWidgetSelectionRange myRange;
    QStringList myFormats;
};
In the class, we save a qtablewidgetselectionrange object and a qtablewidget pointer to get the dragged data. The formats () and retrivedata () functions override the qminedata function. Initialize private variables in the constructor.
TableMimeData::TableMimeData(const QTableWidget *tableWidget,
                             const QTableWidgetSelectionRange &range)
{
    myTableWidget = tableWidget;
    myRange = range;
    myFormats << "text/csv" << "text/html" << "text/plain";
}
QStringList TableMimeData::formats() const
{
    return myFormats;
}
The formats () function returns a list of supported MIME types. The order between types does not affect the program, but it is a good habit to put the "best" format first. Programs that support multiple formats generally use the first matching format.
QVariant TableMimeData::retrieveData(const QString &format,
                                     QVariant::Type preferredType) const
{
    if (format == "text/plain") {
        return rangeAsPlainText();
    } else if (format == "text/csv") {
        return toCsv(rangeAsPlainText());
    } else if (format == "text/html") {
        return toHtml(rangeAsPlainText());
    } else {
        return QMimeData::retrieveData(format, preferredType);
    }
}
Specify a MIME type. The retrievedata () function returns the dragged data as a qvariant data. The value of the format parameter is generally one of the formats () returned lists. We didn't make this assumption, and the application won't check the MIME type when dragging. Functions such as text (), HTML (), URLs (), image-data (), colordata (), and data () are provided by qmimedata. The preferedtype parameter is used to give a recommendation of the qvariant type. Here we ignore this parameter and it is processed by qmimedata.
void MyTableWidget::dropEvent(QDropEvent *event)
{
    const TableMimeData *tableData =
            qobject_cast<const TableMimeData *>(event->mimeData());
    if (tableData) {
        const QTableWidget *otherTable = tableData->tableWidget();
        QTableWidgetSelectionRange otherRange = tableData->range();
        ...
        event->acceptProposedAction();
    } else if (event->mimeData()->hasFormat("text/csv")) {
        QByteArray csvData = event->mimeData()->data("text/csv");
        QString csvText = QString::fromUtf8(csvData);
        ...
        event->acceptProposedAction();
    } else if (event->mimeData()->hasFormat("text/plain")) {
        QString plainText = event->mimeData()->text();
        ...
        event->acceptProposedAction();
    }
    QTableWidget::mouseMoveEvent(event);
}
The dropevent () function is similar to the dropevent () written earlier in this section. In this function, we first convert qmimedata security to tablemimedata. If qobject_cast <t> () returns the correct pointer, it indicates that the toggle occurs in the mytablewidget control of the same application. We can directly obtain the data to be dragged in the table based on the qmimedata API. If no correct pointer is obtained, it is processed in the standard way.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.