通过setItemWidget

时间:2017-10-24 21:21:37

标签: c++ qt drag-and-drop qt5 qtablewidget

我使用QListWidget通过setItemWidget设置自定义小部件来显示它们。像这样:

QListWidget* listWidget = new QListWidget;
listWidget->setAcceptDrops(true);
listWidget->setDragDropMode(QAbstractItemView::InternalMove);
listWidget->setDragEnabled(true);
listWidget->setSelectionMode(QAbstractItemView::SingleSelection);

for ( int i = 0 ; i < 50 ; ++i )
{
    ItemWidget* item = new ItemWidget;
    QListWidgetItem* listItem = new QListWidgetItem;
    listItem->setSizeHint(item->sizeHint());
    listWidget->addItem(listItem);
    listWidget->setItemWidget(listItem, item);
}

ItemWidget派生自QWidget,只是在布局中显示一些自定义数据,如下所示:

ItemWidget::ItemWidget()
{
    QVBoxLayout* layout = new QVBoxLayout;
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);

    QHBoxLayout* contentLayout = new QHBoxLayout;
    contentLayout->setSizeConstraint(QLayout::SetFixedSize);
    contentLayout->setSpacing(0);

    contentLayout->addSpacing(5);
    contentLayout->setContentsMargins(10, 20, 10, 20);

    QLabel* iconLbl = new QLabel;
    iconLbl->setPixmap(QPixmap(":/icon.png"));
    iconLbl->setMaximumWidth(20);
    contentLayout->addWidget(iconLbl, 0, Qt::AlignTop);

    contentLayout->addSpacing(14);

    QVBoxLayout* infoLayout = new QVBoxLayout;
    infoLayout->setContentsMargins(0, 0, 0, 0);
    infoLayout->setSpacing(0);

    QLabel* firstLbl = new QLabel("First line of text");
    infoLayout->addWidget(firstLbl);

    infoLayout->addSpacing(4);

    QLabel* secondLbl = new QLabel("Second line of text");
    infoLayout->addWidget(secondLbl);

    contentLayout->addLayout(infoLayout);

    layout->addLayout(contentLayout);

    setLayout(layout);
}

我想实施阻力&amp; drop可以重新排列列表中的项目。但是,当使用setItemWidget时,当鼠标拖动项目时,只拖动背景矩形(QListWidgetItem?),而没有显示ItemWidget的自定义内容。我喜欢被拖动的项目也包含ItemWidget内容,因此用户可以看到被拖放的内容。

有没有人有实现这个的工作方法?

我已经尝试过使用从QListWidgetItem和QWidget派生的自定义类,并直接在该类中设置自定义布局,因此可能不需要ItemWidget或使用setItemWidget,但它没有成功正如我所希望的那样。

1 个答案:

答案 0 :(得分:1)

要自定义与QPixmap QDrag相关联的QListWidget,我们必须覆盖startDrag()方法。

主要任务是为QPixmap选择的元素QPixmap创建viewport()透明的QPixmap可见图像的大小,然后我们绘制它们选中每个项目的QPainter后,我们会使用QPixmap

要获取每个项目的grab(),请使用visualRect()方法,指明通过#ifndef LISTWIDGET_H #define LISTWIDGET_H #include <QListWidget> #include <QDrag> #include <QMimeData> #include <QPainter> class ListWidget : public QListWidget { protected: void startDrag(Qt::DropActions supportedActions){ QDrag *drag = new QDrag(this); drag->setMimeData(model()->mimeData(selectedIndexes())); QPixmap pixmap(viewport()->visibleRegion().boundingRect().size()); pixmap.fill(Qt::transparent); QPainter painter(&pixmap); for(QModelIndex index: selectedIndexes()){ painter.drawPixmap(visualRect(index), viewport()->grab(visualRect(index))); } drag->setPixmap(pixmap); drag->setHotSpot(viewport()->mapFromGlobal(QCursor::pos())); drag->exec(supportedActions, Qt::MoveAction); } }; #endif // LISTWIDGET_H 获得的矩形。

HOST=gmail-pop.l.google.com
PORT=995

openssl s_client -servername $HOST -connect $HOST:$PORT < /dev/null 2>/dev/null | openssl x509 -outform pem

完整示例可在以下link

中找到