Russian Qt Forum
Ноябрь 24, 2024, 19:41 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Scroll по таблице  (Прочитано 7214 раз)
Виталий
Гость
« : Август 23, 2012, 13:40 »

Добрый день! Помогите пожалуйста мне в решении моей проблемы.
Мне нужно сделать необычный скролл по QTableWidget. Нужно чтобы скролить можно было зажав левую кнопку мыши на ячейке и перетаскивая  вверх/вниз - таблица прокручивается (как на тачскринах(!)). Я сделал это следующим образом. У меня есть класс-наследник от QWidget в нём я переопределяю метод
Код
C++ (Qt)
protected:
   virtual bool eventFilter(QObject *, QEvent *);
Код
C++ (Qt)
 
bool V1::eventFilter(QObject *obj, QEvent *event)
{
   QTableWidget* tmp = dynamic_cast<QTableWidget*> (obj);
   if (event->type() == QEvent::HoverMove && (QApplication::mouseButtons().testFlag(Qt::LeftButton)) || (QApplication::mouseButtons().testFlag(Qt::RightButton)) )
   {
   m_flag=1;
   tmp->verticalScrollBar()->setSliderPosition(tmp->verticalScrollBar()->sliderPosition()+(m_pastCoord-QCursor::pos().y()));
   m_pastCoord=QCursor::pos().y();
   return true;
   }
   return QObject::eventFilter(obj, event);
}
 
void V1::on_listMenu_pressed(const QModelIndex &index)
{
   m_pastCoord = QCursor::pos().y();
   m_flag=0;
}
 

скролл в итоге работает, но возникает странный глюк:
после перетаскивания окна по рабочему столу QTableWidget "думает", что левая кнопка мышки зажата и прокручивается при наведении курсора на него.
В документации к qt написано что QApplication::mouseButtons() возвращает не текущее состояние нажатых кнопок мыши, а последнее зарегистрированное в произошедших ранее событиях.
Отсюда вопрос: можно ли как-то принудительно сбросить состояние мыши (в Qt::NoButton)? Или возможны какие-нибудь еще варианты?
Записан
lighting
Гость
« Ответ #1 : Август 23, 2012, 13:52 »

а чего-бы не переопределить mouseEvent для TableWidget и получать только те события которые нужны?
Записан
Bepec
Гость
« Ответ #2 : Август 23, 2012, 13:58 »

lighting частично прав.

Зачем вы обрабатываете все события ховер, если достаточно поставить фильтр на QTableWidget с целью отлова "MouseMoveEvent".

MouseMoveEvent вызывается только при движении с нажатыми клавишами мыши, которые можно у него же и узнать. При чём это будет 100% достоверная информация Подмигивающий

PS ну в принципе и всё Подмигивающий

Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #3 : Август 23, 2012, 14:03 »

и ещё для Qt-классов желательно использовать qobject_cast вместо dynamic_cast, ну и на 0 проверять полученный указатель
а чего-бы не переопределить mouseEvent для TableWidget и получать только те события которые нужны?
многие очень не любят наследоваться
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Виталий
Гость
« Ответ #4 : Август 23, 2012, 15:03 »

В конструкторе установлен фильтр:
 
Код
C++ (Qt)
V1::V1(QWidget *parent) :
   QWidget(parent),
   ui(new Ui::V1)
{
...
ui->listMenu->installEventFilter(this);
...
}
 
где:
V1 - класс формы, на которой лежит tableWidget;
listMenu - сам tableWidget, событие которого обрабатывается в eventFilter'е.
поставить фильтр на QTableWidget с целью отлова "MouseMoveEvent"
Если я правильно понял, в этом самом eventFilter' е и надо отлавливать mouseMoveEvent? Не подскажете как?
Записан
Bepec
Гость
« Ответ #5 : Август 23, 2012, 15:21 »

Код:
// вот это всё находится в вашем евент фильтре ;)
if (event->type() == QEvent::MouseMove) {
         QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
         if (mouseEvent.button() == Qt::LeftButton) // тут помоему логическая операция должна быть, не помню к сожалению. Но по идее прокатит.
              qDebug() << "Кто то мышку повтыкал да с кнопочкой зажатой левой!!! ";
         return true;
     }

Примерно так.
Записан
Виталий
Гость
« Ответ #6 : Август 23, 2012, 15:38 »

При движении мыши над tableWidget тип события QEvent::HoverMove, а не QEvent::MouseMove.
И после перетаскивания окна по рабочему столу QTableWidget "думает", что левая кнопка мышки зажата и прокручивается при наведении курсора на него, то есть QApplication::mouseButtons().testFlag(Qt::LeftButton) возвращает true. Вопрос и состоит в том, как сбросить состояние мыши в Qt::NoButton.
Записан
Bepec
Гость
« Ответ #7 : Август 23, 2012, 15:49 »

Кхм. Уважаемый вы тыквы любите? А то на них похожи становитесь в моих глазах.

Повторяю в последний раз.
MouseMove вызывается когда вы двигаете мышкой с зажатой клавишей(любой клавишей). Пофиг над чем двигаете.
Соответственно в MouseMove имеются ( в НЁМ, а не в QApplication) адекватные на момент события состояния кнопок.

PS если и это не поймёте, то что с вами делать? :/
Записан
Виталий
Гость
« Ответ #8 : Август 23, 2012, 16:59 »

Тогда я тоже повторюсь: не знаю почему, но тип события при движении мыши - HoverMove, а не MouseMove, специально проверял, выводя event->type() в qDebug. Соответственно входной if не срабатывает. Попробовал такой вариант:
Код
C++ (Qt)
if (event->type() == QEvent::HoverMove)
   {
       QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
       if (mouseEvent->button() & Qt::LeftButton)
       {
           ...
           return true;
       }
   };
Теперь прокрутка работает вообще всегда, когда мышь над tableWidget'ом, даже без нажатых кнопок.
При этом mouseEvent.button() возвращает какую-то чушь, отрицательное длинное целое, десятизначное, при каждом запуске приложения разное, даже если ЛКМ нажата. Как будто нажатие вообще не происходит.
Записан
Bepec
Гость
« Ответ #9 : Август 23, 2012, 18:58 »

Что сказать Улыбающийся Завтра заценю что у вас там такое. Ещё б версию куте привели какую используете Улыбающийся
Записан
Serr500
Гость
« Ответ #10 : Август 23, 2012, 21:39 »

При этом mouseEvent.button() возвращает какую-то чушь, отрицательное длинное целое, десятизначное, при каждом запуске приложения разное, даже если ЛКМ нажата. Как будто нажатие вообще не происходит.
А с чего Вы взяли, что при QEvent::HoverMode вы получите QMouseEvent? В документации явно сказано, что будет QHoverEvent. Эти ошибки - последствия static_cast. Если бы Вы использовали dynamic_cast, то получили бы NULL и поняли, что что-то не так.

Ловите MouseMoveEvent.

MouseMove вызывается когда вы двигаете мышкой с зажатой клавишей(любой клавишей).
Это если mouseTracking выключен. Если включен, то он ловит движения и без кнопок.
Записан
Bepec
Гость
« Ответ #11 : Август 23, 2012, 23:32 »

А по умолчанию, mouseTracking выключен Подмигивающий
Записан
Bepec
Гость
« Ответ #12 : Август 24, 2012, 08:24 »

Чуть сложновато для новичка, да Улыбающийся

На самом деле причина простая - в качестве виджета, отображающего элементы, используется
Код:
QWidget(0xa82e20, name = "qt_scrollarea_viewport") 
.

Потому поправьте код вот так и будет у вас всё работать:
Код:
ui.treeWidget->viewport()->installEventFilter(this);

PS и да, ловить надо всё же MouseMove Подмигивающий
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.122 секунд. Запросов: 23.