Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Kunashir от Февраля 06, 2012, 11:54



Название: QTableView листать мышкой
Отправлено: Kunashir от Февраля 06, 2012, 11:54
День добрый!

Есть такая задача: нужно реализовать листания QTableView с помощью мышки (не колесиком) - зажимаем левую кнопку и водим мышку вниз или вверх.

Как это лучше реализовать.

Пытался переводить это движение в события для колеса, но перемещение становится не соразмерным.


Название: Re: QTableView листать мышкой
Отправлено: Пантер от Февраля 06, 2012, 12:01
Показывай как пробовал. Вообще, тут нужно ловить ивент и юзать что-то типа scroll*.


Название: Re: QTableView листать мышкой
Отправлено: asvil от Февраля 06, 2012, 12:26
В виндовсе нету для такого галочки?


Название: Re: QTableView листать мышкой
Отправлено: Bepec от Февраля 06, 2012, 12:54
В ХРюше нету точно. Хотя в принципе реализуется очень просто. Отлов события, скорость прокрутки рассчитывать из разницы текущего и начального положения. 3-4 порога хватит, я думаю.


Название: Re: QTableView листать мышкой
Отправлено: Kunashir от Февраля 06, 2012, 13:32
Я наверное туплю, но как прокручивать сам QTableView?

scroll () - это перемещение самого виджета.

Сейчас думаю может попытаться программно движать ScrollBar?


Название: Re: QTableView листать мышкой
Отправлено: Bepec от Февраля 06, 2012, 13:38
Ответ лежит в Header'ах, вертикальном и горизонтальном. У них есть функции сдвига ^.^


Название: Re: QTableView листать мышкой
Отправлено: GreatSnake от Февраля 06, 2012, 13:51
Ответ лежит в Header'ах, вертикальном и горизонтальном. У них есть функции сдвига ^.^
Ответ неправльный.
2 Kunashir:
Код
C++ (Qt)
QScrollBar * QAbstractScrollArea::verticalScrollBar () const
QScrollBar * QAbstractScrollArea::horizontalScrollBar () const
Вот их и двигай.


Название: Re: QTableView листать мышкой
Отправлено: Kunashir от Февраля 06, 2012, 13:54
Верес, то что Вы предлагаете не то что я хотел (наверное я плохо донес свою мысль) - этим способом, можно переместить строку относительно других, а мне просто весь список в QTableView хочу скроллить.
GreatSnake, сейчас попробую.


Название: Re: QTableView листать мышкой
Отправлено: Bepec от Февраля 06, 2012, 14:17
Это я уже загнался. ;) Извиняюсь.

С таблицами мучаюсь, вот хедера и лезут :)


Название: Re: QTableView листать мышкой
Отправлено: Kunashir от Февраля 06, 2012, 16:12
Спасибо GreatSnake за наводку.
Следующий код приемлемо работает:

Код:
void CTableView::mouseMoveEvent(QMouseEvent *ev)
{
    if (isLeftButtonPressed)
    {
        int rowCount = model()->rowCount();
        int  rHeight = rowHeight(1);
        QScrollBar * vb = verticalScrollBar ();
        QPoint curPoint = ev->pos();
         int deltaY = clickPoint.y() - curPoint.y();
        vb->setValue(deltaY/rHeight);
    }
    QTableView::mouseMoveEvent(ev);
}

Хм... при детальном рассмотрении это работает только один раз, при втором и раз все возвращается в начало.


Название: Re: QTableView листать мышкой
Отправлено: Bepec от Февраля 06, 2012, 18:37
Из вашего обрубка кода, пожалуй ничто не работает ;)

Если уж выкидываете код, то выкидывайте работающий, а не "я тут у коровы кусок отпилил, но чегой-то он мычать не хочет" ;)

смотрю.

Посмотрел. Я в ужасе. Диавольская комбинация операций, выдающая отрицательное значение ;) и правильно оно не работает.


Update:
Поясни пожалуйста, чего ты хочешь? мгновенного скачка по ячейкам, переворачивания страницы, или плавного движения туда-сюда?


Название: Re: QTableView листать мышкой
Отправлено: Kunashir от Февраля 07, 2012, 08:00
Верес, да это больше размышления в слух, так сказать.
Я даже вчера, по дороге домой понял свою ошибку:
vb->setValue(deltaY/rHeight); - здесь я пытаюсь поменять значение вертикально полосы прокрутки, на значение приведенной дельты у-координаты, что в корне не верно.
Надо так:

Код:
vb->setValue(vb->value() + deltaY/rHeight);

Осталось придумать алгоритм, который будет так рассчитывать эту дельту так, чтобы ячейка, над которой была нажата левая кнопка мыши, до момента отпускания кнопки находилась под указателем мыши.


Название: Re: QTableView листать мышкой
Отправлено: Bepec от Февраля 07, 2012, 08:13
Update:
Поясни пожалуйста, чего ты хочешь? мгновенного скачка по ячейкам, переворачивания страницы, или плавного движения туда-сюда?


Название: Re: QTableView листать мышкой
Отправлено: Kunashir от Февраля 07, 2012, 08:16
Update:
Поясни пожалуйста, чего ты хочешь? мгновенного скачка по ячейкам, переворачивания страницы, или плавного движения туда-сюда?

плавного движения туда-сюда? - в идеале это имитация листания пальцем на тачскрине.


Название: Re: QTableView листать мышкой
Отправлено: Kunashir от Февраля 08, 2012, 14:08
И все же мои мучения увенчались успехом.
Вот что получилось, может кому будет интересно:

Заголовочный файл:
Код:
#include <QTableView>
#include <QPoint>
#include <QScrollArea>
#include <QScrollBar>

class CTableView : public QTableView
{
    Q_OBJECT
public:
    explicit CTableView(QWidget *parent = 0);
    void        mouseMoveEvent(QMouseEvent *);
    void        mousePressEvent(QMouseEvent *);
    void        mouseReleaseEvent(QMouseEvent *event);
signals:
    void    mouseEvent ();
public slots:

private:
    bool        isLeftButtonPressed;
    QPoint    clickPoint;
    QScrollBar * vb;

};

Реализация:

Код:
#include "ctableview.h"
#include <QMouseEvent>
//#include <QScrollBar>
#include <QHeaderView>
#include <QApplication>
#include <QFile>
#include <QDebug>

CTableView::CTableView(QWidget *parent) :
    QTableView(parent)
{
    isLeftButtonPressed = false;

    QFile file(":/html/headerTable.css"); //css file.
    file.open(QFile::ReadOnly);
    QString styleSheet = QLatin1String(file.readAll());
     file.close();
    setStyleSheet(QString(styleSheet));
    setSelectionMode(QAbstractItemView::MultiSelection);
    setSelectionBehavior(QAbstractItemView::SelectRows);
     vb = verticalScrollBar ();
     vb->setSingleStep(1);
}

void CTableView::mouseMoveEvent(QMouseEvent *ev)
{
    emit mouseEvent();
    if (isLeftButtonPressed)
    {
        int  rHeight = rowHeight(1);
        QPoint curPoint = ev->pos();
        int deltaY = (clickPoint.y() - curPoint.y());
        if ( abs(deltaY) > rHeight)
        {
             deltaY = (deltaY/rHeight);
             vb->setValue(vb->value() +  deltaY);//deltaY/rHeight);
             clickPoint = ev->pos();
         }

    }
    QTableView::mouseMoveEvent(ev);
}

void CTableView::mousePressEvent(QMouseEvent *ev)
{
    isLeftButtonPressed = true;
    clickPoint   =   ev->pos();
}

void CTableView::mouseReleaseEvent(QMouseEvent *event)
{
    isLeftButtonPressed = false;

}