【问题标题】:I want to implement right click menus on QTWidgetItems我想在 QTWidgetItems 上实现右键菜单
【发布时间】:2010-01-25 16:21:42
【问题描述】:

我正在做一个 uni 项目,我们的目标是制作一个程序,该程序可以扫描选定目录中的所有 img/video/movie 文件,将它们存储在数据库中,然后以有组织的方式(使用 QTreeWidgetItem)显示它们。程序允许你做一些事情,比如读取文件,打开它们等等。现在,问题是我想右键单击其中一个文件并弹出一个菜单,其中包含许多选项,例如打开目录、删除文件...

我只是不知道如何制作那个右键菜单,我对 QT 有点陌生,我试着做这个:

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

我尝试重新定义 itemClicked 方法,但似乎无法找到如何知道它是否是右键单击,我想我可能以错误的方式尝试它。

我的灵感来自于此:

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

双击执行音乐文件。

如果您需要更多代码部分,请告诉我 :)。

在 andy 的最后一条评论之后编辑以显示新代码:

#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);
}    

即使我删除了 QTreeWidget * treeWidget = new QTreeWidget();行它不起作用,我右键单击时看到菜单,但是当我单击播放时,没有任何反应。

【问题讨论】:

    标签: qt right-click


    【解决方案1】:

    在 QWidget 类中,你可以找到一个方法叫做:

    void setContextMenuPolicy (Qt::ContextMenuPolicy policy) 
    

    使用参数:Qt::ActionsContextMenu(可以通过代码设置,也可以在QtDesigner中设置。)

    然后你可以像这样创建一个 QMenu :

    QTreeWidget* pTreeWidget = new QTreeWidget();
    QAction* pOpenFile = new QAction(tr("Open A File"), pContextMenu);
    
    pTreeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
    pTreeWidget->addAction(pTestCard);
    

    使用它很好,因为您可以在其他菜单中重复使用您的操作,例如,在主窗口菜单中...

    希望对你有所帮助!

    【讨论】:

    • 嗨!谢谢您的回答!我应该在哪里定义 pOpenFile?我想我必须在其中放入与 opennMusic(QTreeWidgetItem *, int) 相同的代码(除非我没有参数:/)即使我主要只需要打开一个菜单,我可以通过使用存储在数据库中的路径单击打开目标目录,遗憾的是,除非我弄错了,QT 只允许您从目录中浏览和选择文件,但实际上并没有打开它们:/.
    • 呃,我建议创建一个方法 openFile 来扫描树,寻找 SelectedItem。然后,根据所选项目,您可以肯定地获得它们的“路径”......所以,我会在你的主窗口中创建 OpenFile,(我想它是你的 treewidget 的父级)......当动作被触发时(右键单击菜单、快捷方式或任何东西)您可以扫描所选项目并执行正确的行为...一旦您选择了项目,这可能会对您有所帮助(我想您使用 QDirModel): QString QDirModel::filePath ( const QModelIndex & index ) const
    • 使用你给我的代码确定右键菜单。它看起来像这样:treeWidget= new QTreeWidget(); QAction* pOpenFile = new QAction(tr("Open repertory"), treeWidget); treewidget->setContextMenuPolicy(Qt::ActionsContextMenu); treeWidget->addAction(pOpenFile);连接(pOpenFile,信号(itemClicked(QTreeWidgetItem *,int)),这个,SLOT(opennMusic(QTreeWidgetItem *,int)));如您所见,重要的是我们可以提取 QTreeWidget * Item 以便播放文件。我们放置的连接不起作用。希望您能再次帮助我们,再次感谢大家!
    • 我认为你不应该那样做......忘记你的连接,而是尝试类似的事情:1)创建一个由 openFile 操作调用的方法...... onactOpenFileTriggered() . 2)当用户点击菜单时,它会触发动作,因此跳转到onactOpenFileTriggered()。 3)在这个方法中,你扫描你的树以获取所有选定的项目(QList QTreeWidget::selectedItems () const),并且对于每个选定的项目,打开音乐......我认为它会工作!
    • 好吧,我决定这样做: QAction* pOpenDir = new Qaction(tr("Read File", treeWidget); treewidget->addAction(pOpenDir); 然后我像这样编写 pOpenDir : pOpenDir() { QtreeWidget * treeWidget= newQTreeWidget(); QtreeWidgetItem * QTreeWidgetI= treeWidget-> currentItem(); openMusic(QTreeWidgetI, 6); ///6是路径所在的Tag,QTreeWidgetI是QTreeWidgetItem * item )//// } 它仍然无法正常工作,也许我必须告诉 pOpenDir 在激活方法时激活它,但我不知道如何:/ 再次非常感谢您的帮助!
    【解决方案2】:

    对于这种情况,有一个事件处理程序:QWidget::contextMenuEvent。除了您不必检查特定的鼠标键这一事实之外,它还有一个优点,即这使用户能够使用键盘创建上下文菜单,或者如果用户正在工作,则可以使用完全不同的方式在通过其他方式请求上下文菜单的平台上。

    【讨论】:

      【解决方案3】:

      您还可以快速查看以下 Qt 示例:http://qt.nokia.com/doc/4.6/phonon-qmusicplayer.html

      这里没有树,但也许你应该尝试认真看看他们如何初始化窗口,他们如何构建 QTableWidget 并填充它以及他们如何使用信号/插槽。

      我还建议您从这个示例中对其进行测试。获取他们的源代码,并尝试修改它以添加右键单击...就像您对树所做的那样...当您让它完美工作时,您会看到它需要 23 秒才能通过它从 Table 到 tree Widget...

      如果您对这个例子有更少的麻烦,请告诉我们...

      编辑:添加一些代码后...

      1) lireMusique 有一个从未使用过的列参数。
      2) item->text(6) 返回一个不能为 NULL 的 QString。 item,可以为NULL,如果是NULL,不测试item,每次进入方法都会崩溃!=NULL。
      3)在 vueArtiste 中,为什么要删除并重新创建 Widget ?我可能会错过一些代码,但是...
      4)你的方法pOpenDir很奇怪......我将它命名为onActOpenDirectoryTriggered()。它是否正确连接到您的 pOpenDir 操作的触发信号?
      5)为什么每次触发动作时都创建一个新的 QTreeWidget ?您的新树与 vueArtiste 中的 treeWidget var 同名!这两个变量的作用域不同,但名称相同!这是灾难的秘诀!

      ...

      我真的建议你阅读 Qt 的一两个模型/视图示例,它们简单明了,做得很好,对你有很大帮助!

      我还建议您遵循严格的命名约定,它们将帮助您避免许多错误和烦人的情况...我还将避免在代码中混合语言(忘记法语,到处使用英语)...在其他话,试着让你的代码更加稳定!

      最后,由于您似乎是法语母语人士,我建议您阅读 Qt4 书籍,例如 this book (1st in french, 2nd in english)。我从这个开始,它将提供您需要的一切以及更多!

      【讨论】:

        猜你喜欢
        • 2014-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-05
        • 1970-01-01
        相关资源
        最近更新 更多