前文使用 QMimeData::setText() 等預置方法存儲標準類型(text/plain、text/html 等)。但若需拖放自定義類對象,或希望延遲數據生成(僅在目標真正需要時轉換),則需繼承 QMimeData 重寫 retrieveData()。
QMimeData::setData() 存多種預轉換好的 QByteArray。簡單但可能導致類爆炸、大數據時性能差。QMimeData,存儲源對象指針與選區信息,按需轉換。靈活、高效、控制力強。QMimeData 接口的完整自定義類。最通用但工作量大。場景:QTableWidget 支持拖放導出 plain/text、text/html、text/csv 三種格式。
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 override; // 支持的 MIME 類型列表
protected:
QVariant retrieveData(const QString &format,
QVariant::Type preferredType) const override;
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;
};
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;
}
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); // 交給基類
}
preferredType 提示期望的 QVariant 類型,這裡簡化處理忽略。
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")) { // 外部 CSV
QByteArray csvData = event->mimeData()->data("text/csv");
// 解析 csvData...
event->acceptProposedAction();
}
else if (event->mimeData()->hasFormat("text/plain")) { // 外部純文本
QString plainText = event->mimeData()->text();
// 解析 plainText...
event->acceptProposedAction();
}
}
data()/text() 時才通過 retrieveData() 生成。本文出自 “豆子空間” 博客,原文地址:https://devbean.blog.51cto.com/448512/288742