tags:

views:

509

answers:

3

Hello!

I am working on a uni project and our goal is to make a program that scans all img/video/movie files on a selected directory, stores them in a database and then shozs them in an organised way (using QTreeWidgetItem). Program allows you to do some stuff like read the files, open them and so on. Now, the problem is that I would like to Right click one of the files and pop up a Menu with many options like Open Directory, delete file...

I just don' know how to make that right click menu, I'm kinda new to QT, I tried making this:

connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(openMenu(QTreeWidgetItem *, int)));

I tried redifining the itemClicked method but can't seem to find how to know if it's a right click and i think I might be trying it the wrong way.

I inspired from this:

connect(treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(opennMusic(QTreeWidgetItem *, int)));

which executes a music file on double click.

If you need more code parts just let me know :).

Thank you!!

Edit after andy's last comment to show new code:

include "affichagemusique.h"

void AffichageMusique::lireMusique(QTreeWidgetItem *item, int column)

{

if(item->text(6)!=NULL)
{
Phonon::MediaSource source(item->text(6));
mediaObject->setCurrentSource(source);
mediaObject->play();
}

}

void AffichageMusique::vueArtiste()

{

layout->removeWidget(treeWidget);
treeWidget = new QTreeWidget();
QAction* pOpenDir = new QAction(tr("Play music"),treeWidget );
treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
treeWidget->addAction(pOpenDir);

.......

}
// later on on the code

void AffichageMusique::pOpenDir()  

{

QTreeWidget * treeWidget = new QTreeWidget();
QTreeWidgetItem * QTreeWidgetI= treeWidget->currentItem();
lireMusique(QTreeWidgetI, 6);

}

Even if I remove the QTreeWidget * treeWidget = new QTreeWidget(); line it wont work, I see the menu when i right click but when I click PLay, nothing happens.

Thanks for your help!

+1  A: 

Hey,

In the QWidget class, you can find a method called :

void setContextMenuPolicy (Qt::ContextMenuPolicy policy) 

With the parameter : Qt::ActionsContextMenu (You can either set it by code or in the QtDesigner.)

Then you can then create a QMenu like this :

QTreeWidget* pTreeWidget = new QTreeWidget();
QAction* pOpenFile = new QAction(tr("Open A File"), pContextMenu);

pTreeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
pTreeWidget->addAction(pTestCard);

It's nice to use this because you can re-use your actions in other menus, for example, in the main window menu...

Hope it helps a bit !

Andy M
Hi! Thank you for your answer! And where should i define pOpenFile? i suppose I'll have to put the same code in it that I have in opennMusic(QTreeWidgetItem *, int) (except I don't have the parameters then :/)Even though I mostly only need to open a menu where I can click on Open Target Directory by using the Path stored in the database, sadly unless I am mistaken, QT only lets you browse and pick files from directories but doesn't actually open them :/.
magnus
Andy M
ok the right click menues using the code you gave me. It looks like this atm:treeWidget= new QTreeWidget();QAction* pOpenFile = new QAction(tr("Open repertory"), treeWidget); treewidget->setContextMenuPolicy(Qt::ActionsContextMenu); treeWidget->addAction(pOpenFile);connect(pOpenFile, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(opennMusic(QTreeWidgetItem *, int)));As you can see, it is important we can extract a QTreeWidget * Item in order to play the file. and the connect we put does not work.Hope you can help us again and thanks again for all!!
magnus
I don't think you should proceed like that... Forget your connect and instead, try something like that : 1) create a method which is called by the openFile action... onactOpenFileTriggered(). 2) When the user click on the menu, it triggers the action and therefore, jump into onactOpenFileTriggered(). 3) In this method, you scan your tree to get all the selected Items (QList<QTreeWidgetItem *> QTreeWidget::selectedItems () const), and for each selected items, open the music... I think it will work!
Andy M
ok so, I decided to do it like this:QAction* pOpenDir = new Qaction(tr("Read File", treeWidget);treewidget->addAction(pOpenDir);then I coded pOpenDir like this:pOpenDir(){QtreeWidget * treeWidget= newQTreeWidget();QtreeWidgetItem * QTreeWidgetI= treeWidget-> currentItem();openMusic(QTreeWidgetI, 6); ///6 is the Tag where the path is located and QTreeWidgetI is a QTreeWidgetItem * item)////}It's still not working, mabe I have to tell pOpenDir to activate a method when it's activated but I don't see how :/Thanks again a lot for your help!!
magnus
Erm, do you create the QTreeWidget in OpenDir ??? I think there are a few mistakes in here... Don't you think ? The easier from that point is, that you edit your own question and copy paste the class that contains the QTreeWidget and all your stuff... Another thing, not related to this precise question, try to avoid like hell magic-numbers like "6"... It doesn't mean anything... Now consider, for example : openMusic(QTreeWidgetI, FILE_PATH_TAG); It's a good practice to avoid magic-numbers !
Andy M
Edited! thanks!
magnus
I answered your edition in a further answer.
Andy M
A: 

There's an event handler for exactly that case: QWidget::contextMenuEvent. Besides the fact that you don't have to check for the specific mouse key, it also has the advantage that this enables the user to create the context menu using the keyboard, or maybe to use a totally different way, if the user is working on a platform where context menus are requested via other means.

balpha
A: 

Hey again,

You could also have a quick look at the following Qt Example : http://qt.nokia.com/doc/4.6/phonon-qmusicplayer.html.

There is no tree in here, but maybe you should try and have a serious look at how they initialise the window, how they build the QTableWidget and populates it and how they use signals/slots.

I would also recommend you to give it a test from this example. Take their source code, and try to modify it to add the right click... The same way you would do for your tree... When you got it to work perfectly, you'll see it will take you 23 seconds to pass it from Table to tree Widget...

Let us know if you have less trouble with this example...

Edit : After you put some code...

1) lireMusique has a column parameter that is never used.
2) item->text(6) returns a QString that cannot be NULL. item, can be NULL, so if it is, you'll crash everytime you enter the method if you don't test item!=NULL.
3) In vueArtiste, why do you remove and recreate your Widget ? I maybe miss some code but...
4) Your method pOpenDir is strange... I would name it onActOpenDirectoryTriggered(). Is it properly connected to your pOpenDir action's trigger signal ?
5) Why creating a new QTreeWidget everytime you trigger on your action ? Your new tree has the same name as the treeWidget var in vueArtiste ! Those two variables don't have the same scope but the same name ! It's a recipe for disaster !

...

I would really suggest you to read one or two model/view example by Qt, they are straightforward, nicely done and it will help you a lot !

I would also suggest that you follow strict naming conventions, they will help you avoiding lot of bugs and annoying situations... I would also avoid mixing languages in the code (forget french, use english everywhere)... In other words, try and be more constant in your code !

Finally, since you seem to be a french native speaker, I would recommend to read a Qt4 book, like this book (1st in french, 2nd in english). I started with this one, it will give everything you need and much more !

Andy M