• 17225阅读
  • 10回复

QTableWidget,QListWidget如何接受外界的拖放数据? [复制链接]

上一主题 下一主题
离线viki
 
只看楼主 倒序阅读 楼主  发表于: 2008-11-18
— 本帖被 XChinux 执行加亮操作(2008-11-30) —
同一个重写了dragEnterEvent,dropEvent的子类,基类是QLabel时能接受外界拖放的数据,可是换成QTableWidget就不行了,调试的时候发现dragEnterEvent是成功执行了的,可是acceptProposedAction()并没有起到效果,光标形状仍是禁止拖放。我看Assistant里QTableWidget,QListWidget这几个我尝试接受外界拖放数据失败的类都有3个虚拟函数dropMimeData,mimeData,supportedDropActions,是不是需要重写他们? 有没有例子哈?我重写了也没用,google也没找到,qt Mailing List里发现一个同样的问题可是没人回答,俩晚上了实在没门儿没门儿了啊~~~
[ 此贴被viki在2008-11-19 09:04重新编辑 ]
离线hanxing30

只看该作者 1楼 发表于: 2008-11-19
QTableWidget类有继承来的方法 setDragDropMode(DragDropMode behavior)

如果要自己重新实现,可以参考QT demo中的例子. <Drag and Drop Examples>
离线water_wf

只看该作者 2楼 发表于: 2008-11-19
那个拖图片的不就是个QLIstwidget 吗
离线vrcats
只看该作者 3楼 发表于: 2008-11-19
好可爱的小猫~
首先查看view的以下属性是否正确设置:
showDropIndicator, DragDropMode, dragDropOverwriteMode
另外,你要drop的数据是什么格式的,建议你用简单的Plain Text做测试,因为很多外部程序的Mime格式和Qt内部格式并不兼容,需要转换。
你说的 这几个虚函数在这几个类和其基类里都有实现,所以你应该不用自己重写。
离线viki
只看该作者 4楼 发表于: 2008-11-19
谢谢各位的回复。例子我都看过了。
demo里面拖图片和托list item那两个例子都是widget之间的拖放,而且可以试一下,list item那个例子它也不能接受外界拖拽过来的数据。demo里面只有dropsite这个例子是接受外部数据的,但是它用的QLabel,这个类跟QListWidget,QTableWidget这些不一样,api里连那几个虚函数都没有。俺总觉得那几个虚函数很诡异……

你们可以试一下,写一个QTableWidget的子类,然后构造里accpetDrop(true),重写dragEnterEvent,dropEvent,肯定接受不了外界数据,就像下面这个,你把基类从QTableWidget改成QLabel就可以,但是用QTableWidget,QListWidget这些就不行

DropTableWidget::DropTableWidget(QWidget *parent)
    : QTableWidget(parent)
{
  setAcceptDrops(true);
}

void DropTableWidget::dragEnterEvent( QDragEnterEvent *event)
{
    if( event->mimeData()->hasFormat("text/plain"))
    {
        event->acceptProposedAction();
    }
}

void DropTableWidget::dropEvent( QDropEvent *event)
{
    //TODO:
}
离线water_wf

只看该作者 5楼 发表于: 2008-11-19
第一:没有dragMoveEvent
第二: 改成event->mimeData()->hasText()
请你在试一下,等你结果
离线viki
只看该作者 6楼 发表于: 2008-11-19
谢谢,但是还是有问题...

1、我只是要接收外界的drop,不需要自定义drag,这样也需要重写dragMoveEvent吗?
2、我把if( event->mimeData()->hasFormat("text/plain"))这句判断去掉,直接acceptProposedAction()都不行。
3、基类由QTableWidget换成QLabel后拖放是正常的,况且就只有那俩函数 ,所以代码应该没错

我重写了mimeTypes,光标倒是对了,变成了可drop,但是dropEvent还没有触发,等下班了我再试试,谢谢各位的关注。

QStringList DropTableWidget::mimeTypes () const
{
    QStringList typeList;
    typeList.append("text/plain");
    return typeList;
}

ps:刚才看了一下QTableWidget的源码,默认的mimeTypes()返回的是“application/x-qabstractitemmodeldatalist”,也就是说不重载该函数应该是接收不了其他格式数据的?!继续摸索ing
[ 此贴被viki在2008-11-19 12:57重新编辑 ]
离线water_wf

只看该作者 7楼 发表于: 2008-11-19
拷贝了一个自己写的例子,给你看下,基本结构:
void QSteTabWidget::dragEnterEvent(QDragEnterEvent *event)
{
    m_dropIndex = -1;
    if(event->mimeData()->hasFormat("type/qstetabwidget"))
        event->accept();
    else
        event->ignore();
}
void QSteTabWidget::dragMoveEvent(QDragMoveEvent *event)
{
    event->acceptProposedAction();
    if(event->mimeData()->hasFormat("type/qstetabwidget")){
        event->setDropAction(Qt::MoveAction);
        int index = tabBar()->tabAt(event->pos());
        int x,y;
        QRect rect;
        if(index != -1){
            rect = tabBar()->tabRect(index);
            if((event->pos().x() - rect.x()) >= rect.width() / 2){
                index += 1;
            }else{
            }
            if(index < count()){
                rect = tabBar()->tabRect(index);
                x = rect.x();
                y = rect.y();
                m_dropIndex = index;
            }else{
                rect = tabBar()->tabRect(count() - 1);
                x = rect.x() + rect.width();
                y = rect.y();
                m_dropIndex = count();
            }
            m_tabInsertLabel.move(mapToParent(QPoint(x,y)));
            m_tabInsertLabel.show();
        }else{
            if(m_tabInsertLabel.isVisible())
                m_tabInsertLabel.hide();
            m_dropIndex = -1;
        }
        event->accept();
    }else{
        if(m_tabInsertLabel.isVisible())
            m_tabInsertLabel.hide();
        event->ignore();
    }
}
void QSteTabWidget::dragLeaveEvent(QDragLeaveEvent *event)
{
    if(m_tabInsertLabel.isVisible())
        m_tabInsertLabel.hide();
    m_dropIndex = -1;
}
void QSteTabWidget::dropEvent(QDropEvent *event)
{
    event->acceptProposedAction();
    if(event->mimeData()->hasFormat("type/qstetabwidget")){
        if(m_dropIndex != -1){
            QByteArray da = event->mimeData()->data("type/qstetabwidget");
            QDataStream datastream(&da,QIODevice::ReadOnly);
            int oldindex;
            datastream >> oldindex;
            emit sigTabMove(oldindex,m_dropIndex);
            m_dropIndex = -1;
            event->setDropAction(Qt::MoveAction);
            event->accept();
        }
    }else{
        event->ignore();
    }
    if(m_tabInsertLabel.isVisible())
        m_tabInsertLabel.hide();
}
离线water_wf

只看该作者 8楼 发表于: 2008-11-19
格式自定义格式的
离线viki
只看该作者 9楼 发表于: 2008-11-19
water_wf,你这个实现的还是Widget之间的拖拽吧?  我遇到的问题是QTableWidget,QTreeWidget,QListWidget这些接收不了外界的数据(比如从浏览器,记事本,资源管理器什么的拖拽过来得数据)
离线water_wf

只看该作者 10楼 发表于: 2008-11-19
自己定义的都能得到,为啥得不到外界的呢?
你把我例子中改成hasText()就可以了,主要看基本结构,move是不可缺少的
快速回复
限100 字节
 
上一个 下一个