我试图在仅包含QListWidgets的QTabWidget(列表)上生成右键单击菜单。我在下面的菜单中单击了标签栏高度的距离,这是预期的,因为上下文菜单应用于QTabWidget。
void onCustomContextMenuRequested(const QPoint& pos) {
QListWidgetItem * item = ((QListWidget*)(lists->currentWidget()))->itemAt(pos);
if (item) showContextMenu(item, QListWidget(lists->currentWidget()).viewport()->mapToGlobal(pos));
}
void showContextMenu(QListWidgetItem* item, const QPoint& globalPos) {
QMenu menu;
menu.addAction(item->text());
menu.exec(globalPos);
}
我可以让菜单显示在鼠标上,同时仍然通过更改
指代其下方100px的项目QListWidget(lists->currentWidget()).viewport()->mapToGlobal(pos));
到
QListWidget(lists->currentWidget()).viewport()->mapToParent(mapToGlobal(pos)));
但是我无法通过菜单来参考我点击的项目。我尝试过转换为父坐标和从父坐标转换为无效。
QPoint pos_temp = ((QListWidget*)(lists->currentWidget()))->viewport()->mapFromParent(pos);
if (item) showContextMenu(item, QListWidget(lists->currentWidget()).viewport()->mapToGlobal(pos_temp));
我还尝试过从全局坐标,以及全局和父对象的组合到不良影响。
那么如何才能获得右键菜单来引用我点击的项目?
答案 0 :(得分:0)
customContextMenuRequested
信号发送的位置是关于建立连接的小部件,在这种情况下,我假设它是主小部件所以当使用itemAt()
QListWidget
时由于此方法等待viewport()
的位置,因此它会抛出不足的值。这些情况下的方法是将该本地位置转换为全局位置,然后将该全局位置映射到最终小部件的本地位置。
在下一部分中,我展示了一个例子。
#include <QApplication>
#include <QTabWidget>
#include <QListWidget>
#include <QVBoxLayout>
#include <QMenu>
class Widget: public QWidget{
Q_OBJECT
QTabWidget *lists;
public:
Widget(QWidget *parent=Q_NULLPTR):QWidget(parent){
lists = new QTabWidget;
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &Widget::customContextMenuRequested, this, &Widget::onCustomContextMenuRequested);
auto layout = new QVBoxLayout(this);
layout->addWidget(lists);
for(int i=0; i<4; i++){
auto list = new QListWidget;
lists->addTab(list, QString("tab-%1").arg(i));
for(int j=0; j<10; j++){
list->addItem(QString("item %1-%2").arg(i).arg(j));
}
}
}
private slots:
void onCustomContextMenuRequested(const QPoint& pos){
QPoint globalPos = mapToGlobal(pos);
QListWidget *list = static_cast<QListWidget *>(lists->currentWidget());
if(list){
QPoint p = list->viewport()->mapFromGlobal(globalPos);
QListWidgetItem *item = list->itemAt(p);
if(item)
showContextMenu(item, globalPos);
}
}
void showContextMenu(QListWidgetItem* item, const QPoint& globalPos) {
QMenu menu;
menu.addAction(item->text());
menu.exec(globalPos);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"
以下link是完整的示例。