Sign in to follow this  
toogreat4u

Qt 4.7 Help with QTreeView

Recommended Posts

I posted this on a Qt specific forum but I saw there were very few responses to the posts that had been up so I decided I would post here since I have had so much luck with getting help on this site.

If you have a suggestion for another site to post this to please feel free to let me know!

Hello everyone,

I am relatively new to Qt programming however I am pretty skilled in C++ programming and so I was hired on as a C++ GUI Programmer for a company. I have ran into a little bit of an issue that I can't seem to figure out. I have a built a QTreeView view that just shows the data in a selected hierarchical fashion. I am trying to enable the user to be able to drag and drop items from one place to another. I have a MainWindow class that inherits from QMainWindow and I am trying to get the MainWindow to catch the dropAction when moving items from one to place to another on the QTreeView (I will call view from now on). In doing so I have set the MainWindow in the constructor to accept drops and then disabled the view from excepting drops. As far as this is concerned it appears to be doing what I want. I then reimplemented the dragEnterEvent so that the MainWindow will know when something is being dragged and again that works as I would expect. Finally, I reimplemented the dropEvent and I am trying to get the correct index of the item that the drop event is trying to drop to so that I can call a function that I have already made that will correctly place the item where it needs to go. I am unable to get the correct index from the QTreeView and I am not sure how to proceed.

Visual example of what I am trying to do:

Question: How do you format normal text in this forum?

Quote:

Before Move: After Move G to Directly underneath A:
- A - A
- B - G
- C - B
- D - C
- E - D
- F - E
- G - F
-H - H


If this isn't formatting the way I would like Ill explain the above:

A is the parent index of B,C, and D. D is the parent index of E and F. G and H only have the default parent index. I am trying to move G from default parent index to have A as its parent index when dropping. However I am unable to get the correct index of A, in this situation index (0,0) with parent item being default parent index (QModelIndex()), to be found by dropEvent.
I have a function that already does exactly what I want but it's dependent on the QModelIndex of the view.

My question is how do I get the dropEvent to give me the correct QModelIndex of the QTreeView to place G in the correct location?

Here is the relevant code:



MainWindow::MainWindow()
{
//.....
setAcceptDrops(true);

//....
}

bool MainWindow::loadFile(const QString &fileName)
{
//...
view->reset();
view->setDragDropMode(QAbstractItemView::DragOnly);
view->setDropIndicatorShown(true);
view->setAcceptDrops(false);
view->setModel(urnTree);
view->setWindowTitle(tr("Urn Description"));

//....
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
event->acceptProposedAction();
}

void MainWindow::dropEvent(QDropEvent *event)
{
cout << "Drop Event has occured!\n";
QPoint curPos = event->pos();
QModelIndex curIndex = view->indexAt(curPos);
curIndex = view->model()->index(curIndex.row(), curIndex.column(), curIndex.parent());
TreeItem *curItem = urnTree->getItem(curIndex);
cout << "Current index is: " << curIndex.row() << "," << curIndex.column() << endl;
cout << "Current item on drop is: " << curItem->data(0).toString().toStdString() << endl;
}



As you can see I am lost in how to get the correct QModelIndex from dropEvent and I am running out of ideas and appreciate any help. Please feel free to ask for more code if necessary.

Thanks!!

Share this post


Link to post
Share on other sites
I have found another forum that responded fast to my Qt specific questions. I know this site isn't geared toward Qt GUI programming so I decided to search other avenues. If anyone is working with Qt and would like to know how I solved it I will be glad to share it with you.

Thanks everyone! (not being sarcastic as this site has been an awesome resource!)

Share this post


Link to post
Share on other sites
Quote:
Original post by toogreat4u
I have found another forum that responded fast to my Qt specific questions. I know this site isn't geared toward Qt GUI programming so I decided to search other avenues. If anyone is working with Qt and would like to know how I solved it I will be glad to share it with you.

Thanks everyone! (not being sarcastic as this site has been an awesome resource!)


I'd be interested to know, I've tried a few forums, but all the Qt ones are terrible. Even the new one Nokia has set up is bad: it reeks of web 2.0, and is a huge pain in the butt to navigate.

Share this post


Link to post
Share on other sites
You should do some checks on the QModelIndex. Because you need to see if it's the problem at the pos index or the model index.

if (index.isNull()) {
....
}

Try using QCursor::pos() [static].

Share this post


Link to post
Share on other sites
Quote:


I'd be interested to know, I've tried a few forums, but all the Qt ones are terrible. Even the new one Nokia has set up is bad: it reeks of web 2.0, and is a huge pain in the butt to navigate.


Alrighty the here is the code and I explain what I did in the code:


void MainWindow::dropEvent(QDropEvent *event)
{
// gives me the position relative to the MainWindow
QPoint curPos = event->pos();

// gives me the position relative to the view from MainWindow
// basically lets view know where the current position is at for the drop
// allowing me to drop on the 'correct' item
curPos = view->mapFrom(this, curPos);

// grab the current index of the view
QModelIndex curIndex = view->indexAt(curPos);

// needed this hear because the mapFrom is obviously not very accurate
// and this made it pick the correct index, but I had to have some way
// of knowing what the previous index was
QModelIndex prevIndex = currentIndex;

// accuracy problem trying to fix it, and again this does a pretty good job
// of making the drop item accurate
curIndex = curIndex.sibling(curIndex().row() - 1, curIndex.column());

// accuracy thing again
if(!curIndex.isValid())
{
curIndex = prevIndex.parent();
}

// .. rest is only relevant to my code specifically



}



So basically curIndex is now the correct position to which you will be dropping the item on. This by no way a suggested method as I was already blasted by two people on a Qt forum!

The best approach is to reimplement QTreeView or QAbstractItemView to do your bidding. However this approach works and is kinda a work around if your not wanting to reimplement the abstract class.

Hope this helps someone!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this