QTableView或QListView如何用手拖动滚动?

时间:2016-04-25 06:25:05

标签: c++ qt

在QGraphicview中,

如果我们设置:ui->graphicsView->setDragMode(QGraphicsView::ScrollHandDrag);

此代码使得graphicsview可以在鼠标按下并拖动的情况下滚动项目。

我们如何将QListView或QTableView作为QGraphicsView?

2 个答案:

答案 0 :(得分:1)

您需要对这些小部件进行子类化,然后重新实现QWidget::mousePressEventQWidget::mousMoveEventQWidget::mouseReleaseEvent。但是,您必须要小心,因为您可能会干扰默认实现(例如选择)映射到这些操作的操作,因此需要稍微调整一下。例如(假设QListView的子类):

void MyListView::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::RightButton) //lets map scrolling to right button
        m_ScrollStart = event->pos(); //QPoint member, indicates the start of the scroll
    else
        QListView::mousePressEvent(event);
}

然后

void MyListView::mouseMoveEvent(QMouseEvent *event)
{
    if(!m_ScrollStart.isNull()) //if the scroll was started
    {
        bool direction = (m_ScrollStart.y() < event->pos().y()); //determine direction, true is up (start is below current), false is down (start is above current)
        int singleStep = (direction ? 10 : -10); //fill in the desired value
        verticalScrollBar()->setValue(verticalScrollBar()->value() + singleStep); 
        //scroll by the certain amount in determined direction,
        //you decide how much will be a single step... test and see what you like 
    }

    QListView::mouseMoveEvent(event);
}

最后

void MyListView::mouseReleaseEvent(QMouseEvent *event)
{
    m_ScrollStart = QPoint(); //resets the scroll drag
    QListView::mouseReleaseEvent(event);
}

答案 1 :(得分:0)

Resurrection一样提到了

  

您将需要对这些小部件进行子类化并重新实现QWidget::mousePressEventQWidget::mousMoveEventQWidget::mouseReleaseEvent

但是下面的代码更适合我们:

class MyListView : public QListView
{
public:
    typedef QListView super;
    explicit MyListView(QWidget *parent = 0);

protected:
    // QWidget interface
    void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE;
    void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE;
    void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE;

private:
    enum DragState {
        DragStopped,
        DragStarted,
        Dragged
    };
    quint8 m_dragState;
    int m_dragStartPos;
};

MyListView::MyListView(QWidget *parent)
    : super(parent)
    , m_dragState(DragStopped)
    , m_dragStartPos(-1)
{
}

void MyListView::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton) {
        m_dragState = DragStarted;
        m_dragStartPos = event->pos().y();
    } else
        super::mousePressEvent(event);
}

void MyListView::mouseReleaseEvent(QMouseEvent *event)
{
    if(m_dragState) {
        m_dragState = DragStopped;
        m_dragStartPos = -1;
        return;
    }
    super::mouseReleaseEvent(event);
}

void MyListView::mouseMoveEvent(QMouseEvent *event)
{
    if(m_dragState != DragStopped) {
        const int itemSize = sizeHintForRow(0) / 2;
        const int distance = qAbs(m_dragStartPos - event->pos().y());
        if(distance > 10)
            m_dragState = Dragged;
        if(distance > itemSize) {
            QScrollBar *scrollBar = this->verticalScrollBar();
            int stepCount = (distance/itemSize);
            if(m_dragStartPos < event->pos().y())
                stepCount = -stepCount; //scrolling up
            scrollBar->setValue(scrollBar->value() + (stepCount * scrollBar->singleStep()));
            m_dragStartPos = event->y();
        }
        return;
    }
    super::mouseMoveEvent(event);
}