I would like to popup a menu, when user clicks on an object in QTreeWidgetItem. I though about catching signal contextMenuRequested from QWidget and then retrieving index from the view using itemAt. But this doesn't seem very pretty. Is there any easier way to be able to call a menu on an item inside a view?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
Write your own custom ItemDelegate and handle the click event in QAbstractItemDelegate::editorEvent
.
You can retreive the data in the cell from the QModelIndex.
In C++ it would look like this:
class ItemDelegate: public QItemDelegate
{
public:
ItemDelegate(ContextMenuHandler *const contextMenu, QObject *const parent )
: QItemDelegate(parent)
, m_contexMenu(contextMenu)
{
}
bool editorEvent(
QEvent * event,
QAbstractItemModel * model,
const QStyleOptionViewItem & option,
const QModelIndex & index )
{
if((event->type()==QEvent::MouseButtonPress) && index.isValid())
{
QMouseEvent *const mouseEvent = qobject_cast<QMouseEvent>(event);
if(mouseEvent && (mouseEvent->button()==Qt::RightButton))
{
return m_contexMenu->showContextMenu(mouseEvent->pos(), index);
}
}
}
ContextMenuHandler *const m_contextMenu;
};
treeWidget->setItemDelegate(new ItemDelegate(contextMenuHandler,treeWidget));
回答2:
I'm using something like this:
self.widget_layers.setContextMenuPolicy(Qt.ActionsContextMenu)
removeLayerAction = QAction("Remove selected layer", self)
self.connect(removeLayerAction, SIGNAL('triggered()'), self.layers_widget_controller.remove_selected_layer)
and check which item triggered the signal by:
selected_item = self.main_window.widget_layers.selectedItems()[0]
回答3:
What I did with the new signal/slot style:
self.treeMenu = QMenu()
self.treeAction = QAction('print', self.treeMenu)
self.treeAction.triggered.connect(self.printTreeItem)
self.treeWidget.addAction(self.treeAction)
@pyqtSlot()
def printTreeItem(self):
print self.treeWidget.currentItem().text(0)
This will open a menu when you right-click within the your treeWidget. And if you click the 'print', in your console it will print out the item which has the current focus, it's the one that you right-clicked.
Note: the current item is not necessary the selected item, the selected item is the one you most recently clicked.