crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

4 страниц V  < 1 2 3 4 >  
Ответить в данную темуНачать новую тему
> Прокрутка в QScrollArea
Алексей1153
  опции профиля:
сообщение 4.3.2019, 11:24
Сообщение #11


фрилансер
******

Группа: Участник
Сообщений: 2879
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Анна,

Цитата
The qobject_cast() function behaves similarly to the standard C++ dynamic_cast(), with the advantages that it doesn't require RTTI support and it works across dynamic library boundaries.
qobject_cast() can also be used in conjunction with interfaces; see the Plug & Paint example for details.


то есть, если у класса есть виртуальные функции(а у всех наследников QObject они по определению есть), то стандартный dynamic_cast будет работать

я им обычно и пользуюсь
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Анна
  опции профиля:
сообщение 4.3.2019, 15:14
Сообщение #12


Активный участник
***

Группа: Участник
Сообщений: 276
Регистрация: 22.5.2008
Из: Зеленоград
Пользователь №: 181

Спасибо сказали: 30 раз(а)




Репутация:   4  


Цитата(Алексей1153 @ 1.3.2019, 20:03) *
Анна,
накидал вот вариант обработчика. В аттаче файлы тестового диалога, создай диалог, чтобы посмотреть работу класса обработчика:

    MyWidget dlg(0);
    dlg.exec();


[attachment=1972:CMyScrollHandler.zip]


При таком варианте прокрутка "затыкается", как только мышка попадает на спинбокс или комбобокс.

Сделаю гибрид.
Правда, у меня есть подозрение, что в моём варианте не вё так просто с sendEvent(). Я считала, что этим вызовом передаю событие колеса, предназначенное дочернему виджету, в область прокрутки. Увы, в какой-то момент при закрытии окна иногда происходит обвал. Как я поняла - попытка удалить стековый экземпляр.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 4.3.2019, 15:37
Сообщение #13


фрилансер
******

Группа: Участник
Сообщений: 2879
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Анна, у меня вроде не затыкается, либо скажи, как в моём примере повторить баг, я попробую


а sendEvent в нашей задаче не нужен

посмотри описание eventFilter :

Цитата
Filters events if this object has been installed as an event filter for the watched object.
In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.


Сообщение отредактировал Алексей1153 - 4.3.2019, 15:35
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Анна
  опции профиля:
сообщение 4.3.2019, 16:12
Сообщение #14


Активный участник
***

Группа: Участник
Сообщений: 276
Регистрация: 22.5.2008
Из: Зеленоград
Пользователь №: 181

Спасибо сказали: 30 раз(а)




Репутация:   4  


Алексей1153,
Цитата(Алексей1153 @ 4.3.2019, 15:37) *
у меня вроде не затыкается, либо скажи, как в моём примере повторить баг, я попробую

Я полностью тело функции к себе скопировала. Правда, у меня не диалог, а QSubWindow, а в нём куча виджетов, среди которых есть виджет, содержащий область прокрутки. Вот этому виджету я создала метод eventFilter()и его (виджет) передаю в installEventFilter() всем спинбоксам и комбобоксам.

Цитата(Алексей1153 @ 4.3.2019, 15:37) *
посмотри описание eventFilter :

Если я просто верну true,как в твоём примере, то событие от колеса не обработается не только спинбоксом, но и, вообще, кем-либо ещё (мне кажется, что "затык" как раз в этом месте и происходит). А мне нужно, чтобы оно обработалось, но не спинбоксом, а областью прокрутки.

Увы, но sendEvent() с принятым в eventFilter() событием, вызывает обвал или зависание при закрытии приложения.

Сообщение отредактировал Анна - 4.3.2019, 17:06
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 4.3.2019, 18:37
Сообщение #15


фрилансер
******

Группа: Участник
Сообщений: 2879
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Раскрывающийся текст
Цитата(Анна @ 4.3.2019, 12:57) *
do {} while(0);

Забавная конструкция! Никогда с такой не сталкивалась, но возможность использовать break; удобна. Про использование в макросах тоже почитала.


"break" можно использовать и из
while(1){break;}

или
for(;;){break;}

, но у
do{}while(0);

преимущество в том, что там continue не работает, да и break в конце невозможно забыть поставить, как в первых двух случаях.

Ну и все эти три случая можно заменить на лямбду, в теле которой в любом месте можно вызвать return
[&]()
{
...
}();


и макросами лучше не пользоваться, сейчас в 99.99% случаев вполне достаточно шаблонов и лямбда-функций с шаблонными параметрами ))



а по теме - щас попробую описанный тобой случай воспроизвести у себя.


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

Нет никаких спонтанных зацеплений колеса за спины и комбы. Но если щёлкнуть по контролу - то колесо работает. То есть, всё как нужно

Давай тогда приложи свой пример, где проблема воспроизводится, я попробую поковырять

Сообщение отредактировал Алексей1153 - 4.3.2019, 18:38
Прикрепленные файлы
Прикрепленный файл  CMyScrollHandler2.zip ( 3.07 килобайт ) Кол-во скачиваний: 96
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Анна
  опции профиля:
сообщение 6.3.2019, 13:52
Сообщение #16


Активный участник
***

Группа: Участник
Сообщений: 276
Регистрация: 22.5.2008
Из: Зеленоград
Пользователь №: 181

Спасибо сказали: 30 раз(а)




Репутация:   4  


Цитата(Алексей1153 @ 4.3.2019, 18:37) *
вот я добавил туда вложенный виджет класса QScrollArea. Обработчик даже не пришлось трогать, благодаря рекурсивному поиску чайлдов.


Увы, свой виджет дать не могу. У меня нет доступа в интернет с компа, но он не сильно отличается от первого варианта.

Вся печаль заключается в том, что когда я полностью подставила твой класс (правда, мой компилятор не всегда понимает твой код, пришлось подправить), то возникает проблема при закрытии приложения: либо приложение остаётся висеть в памяти (даже под отладчиком),, либо возникает ошибка "CRT detected that the application wrote to memory after end of heap buffer". Ошибка возникает только, если на виджете провернуть колесо. Это какой-то бред собачий. Но я под отладчиком виду как вызывается деструктор моего виджета, и дальше всё гибнет уже в глубинах куты.

У меня vc 2010.

В общем, стабильно работает вариант, когда eventFilter() является методом самого виджета, а вместо

return true;

стоит вызов

sendEvent(scrollArea->widget(),event)


Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 6.3.2019, 14:29
Сообщение #17


фрилансер
******

Группа: Участник
Сообщений: 2879
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Анна, Свой виджет давать не надо, просто накидай в новом проекте пример, где баги воспроизводятся. Тогда можно будет глянуть, что там


без рассмотрения кода ничего подсказать не смогу. Но точно уверен, что sendEvent там не нужен. Поймать краш тоже только в отладке смог бы, либо увидел бы, что ты что-то не так делаешь.

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

Сообщение отредактировал Алексей1153 - 6.3.2019, 14:30
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Анна
  опции профиля:
сообщение 6.3.2019, 16:32
Сообщение #18


Активный участник
***

Группа: Участник
Сообщений: 276
Регистрация: 22.5.2008
Из: Зеленоград
Пользователь №: 181

Спасибо сказали: 30 раз(а)




Репутация:   4  


Цитата(Алексей1153 @ 6.3.2019, 14:29) *
накидай в новом проекте пример, где баги воспроизводятся. Тогда можно будет глянуть, что там


Я скомпелила твой код. Прокручивается до тех пор, пока курсор мыши не наскочет на спинбокс или комбобокс. Если курсор мыши изначально находится на боксе (но у бокса фокуса нет), то кручение колеса не обрабатывается.

А что касается изменений, то пришлось убрать инициализацию
scrollArea =0
И цикл for(auto* child:list) заменила на обычный for(int i=0; i < list.count();i++) и в теле child на list.at(i).


Честно говоря, я не совсем понимаю, почему боксы, вообще, хватают фокус, когда крутится колесо, если у них установлен StrongFocus.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 6.3.2019, 17:56
Сообщение #19


фрилансер
******

Группа: Участник
Сообщений: 2879
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(Анна @ 6.3.2019, 18:32) *
А что касается изменений, то пришлось убрать инициализацию
scrollArea =0

нельзя просто взять и убрать инициализацию, переноси в конструктор

Цитата(Анна @ 6.3.2019, 18:32) *
я не совсем понимаю, почему боксы, вообще, хватают фокус

- значит, для них не установлен фильтр. У меня всё работает, как задумано.

Поставь следующий эксперимент: для сообщения простого движения курсора (mouseMove) выведи в лог дебага какое-нибудь сообщение
qDebug()<<"..."

- порасставляй таких выводов повсюду, где нужно проследить поведение кода. Будешь шевелить мышкой и в реальном времени видеть, что куда летит
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Анна
  опции профиля:
сообщение 6.3.2019, 19:16
Сообщение #20


Активный участник
***

Группа: Участник
Сообщений: 276
Регистрация: 22.5.2008
Из: Зеленоград
Пользователь №: 181

Спасибо сказали: 30 раз(а)




Репутация:   4  


Цитата(Алексей1153 @ 6.3.2019, 17:56) *
нельзя просто взять и убрать инициализацию, переноси в конструктор

Она и так инициализируется в конструкторе. Ты же передашь туда указатель на QScrollArea.

С остальным попробую уже в понкдельник. Все Добби женского пола завтра свободны!

Одного жалко - столько времени на такую дребедень ушло. Утешает, что хоть что-то новенькое узнала, а то сплошная рутина: создай форму, выведи нанные в форме, получи данные из формы... И так десятки раз.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

4 страниц V  < 1 2 3 4 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 26.6.2019, 13:44