【问题标题】:Custom multiple selection for QListWidgetQListWidget 的自定义多项选择
【发布时间】:2012-05-18 16:42:25
【问题描述】:

我有基于拆分器视图的​​ Qt 应用程序:左侧是 QListWidget,其中包含可以选择的文件;所选文件的内容以适当的格式显示在拆分器的右侧。这部分工作正常。

我现在需要添加比较功能:如果在 QListWidget 中选择了一项,则其内容显示在右侧;如果选择了另一个项目而不是我想显示差异结果。 (事情比这要复杂一些,因为并非所有项目都可以区分。)

我想要做的是保持单一选择功能不变,但也启用 only CTRL + 鼠标单击以进行第二次选择。我尝试使用 QAbstractItemView::ExtendedSelection ,然后过滤掉 Shift 和鼠标拖动,但这种方法没有运气:虽然我可以使用 keyPressEvent() 捕获 Shift 键,但我无法阻止选择(我希望只删除事件就足够了);至于拖动,我使用 mouseMoveEvent() 希望在状态更改为 DragSelectingState 时删除事件,但这也不起作用。

然后我考虑坚持单选,但在右键单击第二个项目时打开上下文菜单 - 虽然右键单击确实会发出 itemSelectionChanged() 信号,但我还没有弄清楚该怎么做,因为我不知道知道哪个项目被右键单击。

欢迎任何其他不涉及添加额外 UI 元素的创意建议——我不能有任何额外的按钮、组合框等。

【问题讨论】:

    标签: qt qlistwidget multipleselection custom-sections


    【解决方案1】:

    仍然没有弄清楚如何将 QListWidget 中的选择限制为一两个,但右键单击第二个项目时会出现上下文菜单。

    只需将选择模式设置为 QAbstractItemView::SingleSelection 然后重新实现 mousePressEvent() 和 contextMenuEvent()。

    class MyListView : public QListWidget
    {
      Q_OBJECT
    
      public:
        ListView();
        virtual ~ListView() {}
    
        /** Add item to the list. 
            @param itemName Item's display name.
            @param itemHandle Value to return if item selected.
        */
        void AddItem(const QString itemName, const quint32 itemHandle);
    
      private slots:
        void slot_ItemSelectionChanged(void);
        void slot_Option1(void);
        void slot_Option1(void);
    
      signals:
        void signal_ItemSelectionChanged(const qint32 itemHandle);
    
      private:
        void mousePressEvent(QMouseEvent* mousePressEvent);
        void contextMenuEvent(QContextMenuEvent* menuEvent);
    
        QListWidgetItem *m_selectedItem;        ///< Pointer to the currently selected item.
        QListWidgetItem *m_rightClickedItem;    ///< Pointer to right-clicked item in the list.
        QAction* m_menuOption1;                 ///< Menu option 1.
        QAction* m_menuOption2;                 ///< Menu option 2.
        QMenu* m_myListContextMenu;             ///< Menu with all List View menu actions.
    };
    
    MyListView::MyListView()
    {
      setSelectionMode(QAbstractItemView::SingleSelection);
    
      // create my context menu with 2 options
      m_menuOption1 = new QAction(tr("option 1"), this);
      m_menuOption1 ->setEnabled(true);
    
      m_menuOption2 = new QAction(tr("option 2"), this);
      m_menuOption2 ->setEnabled(true);
    
      m_myListContextMenu = new QMenu(this);
      m_myListContextMenu ->addAction(m_menuOption1);
      m_myListContextMenu ->addAction(m_menuOption2);
    
      bool allConnected = true;
      // process primary selection
      allConnected &= connect(this, SIGNAL(itemSelectionChanged(void)), this, SLOT(slot_ItemSelectionChanged(void)));
      // process menu option 1
      allConnected &= connect(m_menuOption1, SIGNAL(triggered()), this, SLOT(slot_Option1()));
      // process menu option 2
      allConnected &= connect(m_menuOption2, SIGNAL(triggered()), this, SLOT(slot_Option2()));
    
      if (!allConnected )
      {
        assert(0);
      }
    }
    
    void ListView::slot_ItemSelectionChanged(void)
    {
      if (currentItem() != m_selectedItem)
      {
        m_selectedItem = currentItem();
        emit signal_ItemSelectionChanged(m_selectedItem->type());
      }
    } // end of method slot_ItemSelectionChanged()
    
    void MyListView::contextMenuEvent(QContextMenuEvent* menuEvent)
    {
      m_rightClickedItem = itemAt(menuEvent->pos());
    
      // do my prep stuff here specific to right-clicked item 
      // in case one of menu options gets selected
    
      m_listMenu->exec(menuEvent->globalPos());
    } // end of method contextMenuEvent()
    
    void MyListView::mousePressEvent(QMouseEvent* mousePressEvent)
    {
      // drop right mouse button event as it would otherwise cause a change of selection
      if (!(mousePressEvent->buttons() & Qt::RightButton))
      {
        QListWidget::mousePressEvent(mousePressEvent);
      }
    } // end of method mousePressEvent()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多