Drag & Drop using QTableWidget
I'm trying to implement Drag & Drop using a QTableWidget and I haven't been having much luck. I've been trying to get a hold of the QTableWidgetItem that the cursor is over using the itemAt(int x, int y) function using the QMouseEvent event but I keep getting a NULL pointer.
Code:
void table_widget
::mousePressEvent(QMouseEvent *event
) { popupMenu->addAction("Drag");
popupMenu->addAction("Drop");
if (event->button() == Qt::RightButton) {
popupMenu
->popup
(QPoint(event
->x
()+216,event
->y
()+130),
0);
printf("%x\n",itemAt(event->x()+216,event->y()+130));
}
}
The 216 and 130 are just offsets from the top left corner of the GUI to the top left corner of the first cell in the table.
Any suggestions?
Re: Drag & Drop using QTableWidget
For drag and drop, take a look at Using Drag and Drop with Item Views - Using Convenience Views.
For context menu, you might want to reimplement contextMenuEvent() instead. More or less something like this:
Code:
popupMenu.addAction(...);
popupMenu.exec(event->globalPos());
}
Re: Drag & Drop using QTableWidget
I fixed that problem, I just had to create a new QTableWidgetItem for each cell in the table.
I did have another question though, for dropEvent, it doesnt seem like the function is being called. I have it set up so that it prints a message when it enters that function but the message is never displayed. What could be wrong?
Here's the code for that function:
Code:
{
printf("dropEvent\n");
event->acceptProposedAction();
}
I even tried inserting if (event->mimeData()->hasText()) before the printf() statement but that doesnt really do anything.
Re: Drag & Drop using QTableWidget
Hello,
You have to do those two steps :
1 - call setAcceptDrops(true) on your tablewidget
2 - reimplement dragEnterEvent method, and accept it !
I'm not sure if the second step is absolutely necessary for a tablewidget, but the first is, for sure :)
Guilugi
Re: Drag & Drop using QTableWidget
I just had to reimplement dragMoveEvent() and it worked fine, thanks.
Now I'm having another 'problem'. In my project I'm trying to drag and drop from one QTableWidget to another but I can't quite get it right. The dragEnterEvent acknowledges when I've entered another QTableWidget but thats about it. Here's what I'm working with:
Code:
{
if (test != 0)
{
if ( event->source() == this ) // same table, move entry
{
event->setDropAction( Qt::MoveAction );
event->accept();
}
else // different table, add entry
{
printf("Different table\n");
event->acceptProposedAction();
}
source = itemAt(event->pos());
source->setText(itemAt(event->pos())->text());
}
}
{
printf("I'm in dropEvent\n");
itemAt(event->pos())->setText(source->text());
if(source != itemAt(event->pos()))
source->setText("");
event->acceptProposedAction();
}
{
event->setDropAction(Qt::MoveAction);
event->accept();
}
Any suggestions?
Re: Drag & Drop using QTableWidget
I have exactly the same problem. I called set setAcceptDrops(true) and reimplemented dragEnterEvent(QDragEnterEvent *event), which gets called and I accept the proposed copy-action.
However, my reimplemented dropEvent function is never called. The documentation and examples say it will be called, but I couldn't get this to work :-(
Btw, this is Qt Open Source 4.2.2.
Any suggestions?
Re: Drag & Drop using QTableWidget
Correction to my last post: It is Qt Open Source 4.2.1
I believe I have found the problem. In qtablewidget.h, in the class declaration for QTableWidget the function dropEvent() is not declared as virtual, thus our reimplemented dropEvent() function will never be called.
I guess I have to check with 4.2.2 and see if this was fixed...
Andreas
Re: Drag & Drop using QTableWidget
Quote:
Originally Posted by
ghorwin
I believe I have found the problem. In qtablewidget.h, in the class declaration for QTableWidget the function dropEvent() is not declared as virtual, thus our reimplemented dropEvent() function will never be called.
It's declared virtual in QWidget.
http://www.qtcentre.org/forum/p-reim...ostcount5.html
Re: Drag & Drop using QTableWidget
Yes, that's why it works when you inherit from QTableView... however, QTableWidget provides its own implementation of dropEvent() without declaring it virtual. Therefore classes deriving from QTableWidget will not be able to reimplement that function, or if they do the function will never get called.
Andreas
Re: Drag & Drop using QTableWidget
Actually, it doesn't matter if QTableWidget marks it virtual or not. It has already been declared as virtual in the base class, in QWidget that is.
Quote:
Originally Posted by
jacek
Once a method was declared as virtual, it will be virtual in all subclasses, regardless if one uses the "virtual" keyword or not.
Re: Drag & Drop using QTableWidget
jpn: I have to agree. The problem must lie elsewhere.
A test-implementation using QTableView showed the same behavior - the dragEnterEvent() is called correctly but despite the fact, that acceptProposedAction() is called, the reimplemented dropEvent() function is never called.
Did anyone manage to implement drag&drop with QTableView or QTableWidget already? What is missing to get this to work?
Andreas
Re: Drag & Drop using QTableWidget
Quote:
Originally Posted by
ghorwin
A test-implementation using QTableView showed the same behavior - the dragEnterEvent() is called correctly but despite the fact, that acceptProposedAction() is called, the reimplemented dropEvent() function is never called.
Is the drag move event accepted?
Re: Drag & Drop using QTableWidget
Bump. ghorwin 'hijacked' my thread!
Re: Drag & Drop using QTableWidget
Israa: Sorry for hijacking, but you asked excactly the same question that I had, so figured opening a new thread would be non-sense.
Jpn: dragMoveEvent() is called correctly.
So it seems something prevents the dropping...
If I read the documentation correctly, only the widget itself, that should accept the drop, needs to call setAcceptDrop(), right? Or do I also have to tell the parent dialog to accept drops?
Anyway, I'm clueless. Should I post a simple test-program?
Re: Drag & Drop using QTableWidget
Quote:
Originally Posted by
ghorwin
Jpn: dragMoveEvent() is called correctly.
Yes, but do you accept the event? :)
Re: Drag & Drop using QTableWidget
Guys, got it to work!!!
The trick is to call
in addition to
Code:
setAcceptDrops(true);
(wasn't mentioned in the docu, but I just went back to the abstract view class)...
Now dropEvent is called alright!
Re: Drag & Drop using QTableWidget
Still something strange about the dropping...
Explain that: When I reimplement the dragMoveEvent() (even with an empty function), I can drop anywhere in my table. If I don't reimplement it, I can only drop when the cursor is exactly on the frame around the content rows (so at the bottom of the header row and at the top of the horizontal scroll bar). That's weird, if you ask me.
So, the recipe for dropping on QTableWidget is:
1. setup your table in the constructor
Code:
setAcceptDrops(true);
2. re-implement the functions dragEnterEvent(...), dragMoveEvent(...) and dropEvent(...), for example:
Code:
{
if (event->mimeData()->hasUrls()) {
event->acceptProposedAction();
}
}
// nothing to do, function just has to exist...
}
{
if (event->mimeData()->hasUrls()) {
QList<QUrl> urls = event->mimeData()->urls();
for (int i=0; i<urls.count(); ++i) {
int row = rowCount();
insertRow(row);
setItem(row, 0, newItem);
}
event->accept();
}
}
At least that's what worked for me.
Re: Drag & Drop using QTableWidget
I still haven't gotten an answer to my question, would anyone know what I need to do to enable drag & drop to and from 2 QTableWidgets? I create a class that inherits QTableWidget and I place the two objects on either side of a QSplitter. I can drag & drop in the same table, but not to the other table.
Re: Drag & Drop using QTableWidget
Using Drag and Drop with Item Views - Using Convenience Views:
Quote:
For example, we can enable drag and drop in a list widget with the following lines of code:
Code:
listWidget->setDragEnabled(true);
listWidget->setAcceptDrops(true);
listWidget->setDropIndicatorShown(true);
The same applies for a table widget.
Re: Drag & Drop using QTableWidget
Quote:
Originally Posted by
Israa
I still haven't gotten an answer to my question, would anyone know what I need to do to enable drag & drop to and from 2 QTableWidgets? I create a class that inherits QTableWidget and I place the two objects on either side of a QSplitter. I can drag & drop in the same table, but not to the other table.
I am having the same problem, trying to drag&drop from one table to another.
Quote:
Originally Posted by
jpn
I am having trouble following the page you linked. I have tried the function calls that enable drag&drop functionality, but I am still having issues dropping to a different table than was dragged from. Is there any way some short example code could be provided? Nothing complicated, I'd just like to see a working example.
Thanks.