2012-05-10 5 views
1

У меня есть приложение Qt с видом на основе сплиттера: с левой стороны находится QListWidget, содержащий файлы, которые можно выбрать; содержимое выбранного файла отображается в соответствующем формате с правой стороны разделителя. Эта часть работает нормально.Пользовательский множественный выбор для QListWidget

Теперь мне нужно добавить функцию сравнения: если в QListWidget выбран один элемент, то его содержимое отображается с правой стороны; если выбран другой элемент, вместо того, чтобы отображать результат сравнения. (Вещи немного сложнее, потому что не все предметы могут быть различны.)

Что я хотел бы сделать, так это иметь единственную возможность выбора, но затем включить только CTRL + click click for second выбор. Я попытался использовать QAbstractItemView :: ExtendedSelection, а затем отфильтровать перетаскивание Shift и мышью, но мне не повезло с этим подходом: пока я мог захватить клавишу Shift с помощью keyPressEvent(), я не мог предотвратить выбор (я надеялся, что просто отбросить событие будет достаточно); как для drag Я использовал mouseMoveEvent(), надеясь сбросить событие, когда состояние изменится на DragSelectingState, но это тоже не сработало.

Я рассмотрел вопрос о том, t знать, какой элемент был щелкнут правой кнопкой мыши.

открыты для любых других творческих предложений, которые не связаны с добавлением дополнительных элементов пользовательского интерфейса - я не могу иметь какие-либо дополнительные кнопок, комбинированные окна и т.д.

ответ

0

До сих пор не выяснили, как ограничить выбор в 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() 
Смежные вопросы