2012-05-10 7 views
1

저는 Splitter 기반 뷰를 가진 Qt 애플리케이션을 가지고 있습니다 : 왼쪽에는 선택할 수있는 파일을 포함하는 QListWidget이 있습니다. 선택한 파일의 내용은 스플리터 오른쪽에 적절한 형식으로 표시됩니다. 이 부분은 잘 작동합니다.QListWidget에 대한 사용자 정의 다중 선택

이제 비교 기능을 추가해야합니다. 하나의 항목이 QListWidget에서 선택되고 그 내용이 오른쪽에 표시됩니다. 다른 항목을 선택한 경우 대신 diff 결과를 표시하고 싶습니다. (모든 항목이 다를 수는 없기 때문에 상황이 조금 복잡합니다.)

단일 선택 기능을 그대로 유지 한 상태에서 만 사용하면 두 번째로 Ctrl + 마우스를 클릭하십시오. 선택. QAbstractItemView :: ExtendedSelection을 사용하여 시도한 다음 Shift 및 마우스 끌기를 필터링했지만 그 접근 방식에는 운이 없었습니다. keyPressEvent()로 Shift 키를 캡처 할 수 있었지만 선택을 막을 수는 없었습니다 (이벤트를 삭제하면 충분할 것입니다). 드래그의 경우 mouseMoveEvent()를 사용하여 상태가 DragSelectingState로 바뀌었을 때 이벤트를 삭제하려고했지만 그 중 하나가 작동하지 않았습니다.

나는 단일 선택을 고집하지만 두 번째 항목을 마우스 오른쪽 버튼으로 클릭하면 컨텍스트 메뉴가 열리는 것을 고려했다. 오른쪽 클릭이 itemSelectionChanged() 신호를 내 보낸다는 것을 알았지 만, 어떤 항목을 마우스 오른쪽 버튼으로 클릭했는지 알 수 없습니다.

추가 UI 요소를 추가 포함하지 않는 다른 창조적 인 제안을 열기 - 나는 여분의 버튼을 가질 수 없습니다, 콤보 상자 등 여전히

답변

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()