QListWidget的自定义选择
问题描述:
我有Qt应用程序与基于分割器的视图:在左侧是QListWidget包含可以选择的文件;选定文件的内容将以适当的格式显示在分离器的右侧。这部分工作正常。QListWidget的自定义选择
我现在需要添加比较功能:如果在QListWidget中选择了一个项目,则其内容显示在右侧;如果选择另一个项目,而不是我想显示比较结果。 (事情比这更复杂一些,因为不是所有的项目可以diff'ed。)
我想什么做的是有一个单一的选择能力不变,但随后也使只有 CTRL +鼠标点击第二选择。我尝试使用QAbstractItemView :: ExtendedSelection,然后筛选出Shift和鼠标拖动,但没有这种方法运气:虽然我可以捕获Shift键keyPressEvent()我无法阻止选择(我希望只是放弃事件就足够了);至于拖我用mouseMoveEvent()希望在状态改变为DragSelectingState时删除事件,但也没有工作。
然后,我认为坚持单选,但打开右键单击第二项上下文菜单 - 而右键单击确实发出itemSelectionChanged()信号,我还没有想出如何处理这个,因为我不'不知道哪个项目被右键单击。
打开任何其他创造性的建议不涉及添加额外的UI元素 - 我不能有任何多余的按键,组合框等
答
仍然没有想出如何限制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()