首页 > 解决方案 > 将 QHeaderView 中的位置映射到滚动视口的上下文

问题描述

我有一个 QHeaderView 在单击节标题中心的左侧或右侧时会执行一些操作。

为此,我需要知道点击相对于 QHeaderView 的viewport的(可能滚动的)内容的位置。然而,实际的点击位置仅指 QHeaderView(它始终是固定的)。

我尝试了 mapTo/From 的变体,但找不到正确的方法。这是简化的代码:

void MyTableHeader::headerSectionClicked(int section_index, int click_pos)
{
    int section_size = sectionSize(0); // All sections in a header are equally sized
    int section_center = (section_size * (section_index+ 1)) - (section_size / 2); // Center of the clicked section

    if (section_index>= 0)// if mouse is over an item
    {
        if (orientation() == Qt::Horizontal)
        {
            QPoint x_pos = QPoint(click_pos, 0);
            int mapped_offset = viewport()->mapFrom(this, x_pos).x();

            if (mapped_offset != -1)
            {
                // If the click was to the right of the center, iterate on the index
                if (mapped_offset >= section_center)
                {
                    section_index++;
                }
            }
        }
        else
        {
            // Same thing for the Y-dimension
        }
    }

    // Neat stuff after this
}

出现问题的部分是我想找出点击发生在该部分的哪一侧。

// If the click was to the right of the center, iterate on the index
if (mapped_offset >= section_center)
{
    in_index++;
}

mapped_offset未正确引用与部分中心相同的上下文。

标签: qtwidgetqtableviewqheaderview

解决方案


以下解决方案可能会让您知道该怎么做。

MyHeaderView.h

#pragma once

#include <QHeaderView>

class MyHeaderView : public QHeaderView
{
    Q_OBJECT
public:
    MyHeaderView(Qt::Orientation orientation, QWidget* parent = nullptr);
};

MyHeaderView.cpp

#include "MyHeaderView.h"
#include <QDebug>

MyHeaderView::MyHeaderView(Qt::Orientation orientation, QWidget* parent) : QHeaderView(orientation, parent)
{
    setSectionsClickable(true);
    connect(this, &MyHeaderView::sectionClicked, [this](int section)
        {
            QRect currentSectionRect;
            currentSectionRect.setRect(sectionViewportPosition(section), 0, sectionSize(section), viewport()->height());
            auto pos = QCursor::pos();
            auto localPos = mapFromGlobal(pos);

            qDebug() << currentSectionRect << localPos;
            qDebug() << currentSectionRect.contains(localPos); //"Always true!"
        });
}

主文件

#include "MyHeaderView.h"
#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>

int main(int argc, char **args)
{
    QApplication app(argc, args);
    auto model = new QStandardItemModel;
    auto view = new QTableView;
    view->setModel(model);
    model->setRowCount(4);
    model->setColumnCount(4);
    view->setHorizontalHeader(new MyHeaderView(Qt::Horizontal));
    view->show();
    app.exec();
}

推荐阅读