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



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

我也试图从全局坐标,以及全局和父级的组合,产生不良效果。

那么我怎样才能获得右键单击菜单来引用我正在点击的项目呢?

customContextMenuRequested信号发送的位置是相对于建立连接的小部件的,在这种情况下,我假设它是主小部件,因此当使用QListWidget itemAt()时,它会抛出不足的值,因为此方法等待相对于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"

以下链接是完整示例。

相关内容

  • 没有找到相关文章