Q开发了一个桌面程序,因为要在触屏 Windows 系统下使用,为了美观所以去掉了 QListWidget 的滚动条。当实际应用当中发现,当控件中数据过多时,翻看数据效果很不理想,达不到移动端滑动翻看数据的流畅效果。于是打算重载 QListWidget 类,实现点击滑动效果。

首先想到的是重新实现 mouseMoveEventmousePressEvent 这两个函数,所有就从这两个函数入手。要想实现滑动效果,就要让控件移动起来,想到的是 QWidget::scroll 函数。

scroll-qt-assistant

结果不尽人意,原来 scroll 函数移动的是控件的原点,实际效果如下图:

QListWidget左键滑动错误效果

然后只能使用 Qt 自带的 void QAbstractScrollArea::wheelEvent(QWheelEvent * e) 函数实现,唯一的难点就是 QWheelEvent 参数的值,查看 QWheelEvent 的帮助文档,根据说明构造一个参数即可。实际运行效果还算理想。

QWheelEvent-qt-assistant

主要代码如下:

#ifndef QLISTWIDGETEX_H
#define QLISTWIDGETEX_H
#include <QtWidgets>

class QListWidgetEx : public QListWidget
{
public:
    QListWidgetEx(QWidget *parent = 0);

protected:
    void mouseMoveEvent(QMouseEvent* event);
    void mousePressEvent(QMouseEvent* event);

private:
    // 用于记录上一次的y坐标
    int m_y;
};

#endif // QLISTWIDGETEX_H
#include "qlistwidgetex.h"

QListWidgetEx::QListWidgetEx(QWidget *parent)
    :QListWidget(parent)
{
    //m_y = -1;
    // 设置垂直滚动条按像素滚动,如果使用ScrollPerItem按项滚动会感觉到卡顿
    setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
}

void QListWidgetEx::mouseMoveEvent(QMouseEvent *event)
{
    // 只有当鼠标左键按下时才触发
    if (event->buttons() == Qt::LeftButton)
    {
        //
        // scroll(0, event->pos().y()-m_y);   // 错误的代码
        // 根据实际需要的效果设置qt4Delta
        int qt4Delta = (event->y() - m_y) * 2;

        QWheelEvent e = QWheelEvent(event->pos(), event->globalPos(), QPoint(0, 0), QPoint(0, 0),
                                    qt4Delta, Qt::Vertical, Qt::NoButton, Qt::NoModifier);
        wheelEvent(&e);
        m_y = event->y();
    }
}

void QListWidgetEx::mousePressEvent(QMouseEvent *event)
{
    m_y = event->y();
    QListWidget::mousePressEvent(event);
}

效果如下图所示:

QListWidget左键滑动效果

标签: Qt, QListWidget左键滑动, Qt ListWidget 滑动, QListWidget滑动

添加新评论