如何将QTabWidget坐标转换为其子坐标?

时间:2018-03-17 03:15:23

标签: c++ qt qt5 c++14

我试图在仅包含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));

我还尝试过从全局坐标,以及全局和父对象的组合到不良影响。

那么如何才能获得右键菜单来引用我点击的项目?

1 个答案:

答案 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是完整的示例。