![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
XpycT |
![]()
Сообщение
#1
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Всем доброго времени суток
![]() С Qt знаком всего полторы недели, и то, все это время читал книги. Вот захотелось реализовать виджет выбора рисунка (не хочется делать просто текстовое поле с адресом). За основу взял исходники примера с гита Qt. Но к моему сожалению понял, что прочитанных разделов о графике в книгах не достаточно ![]() Хочется сделать что-то типа такого : Но напоролся на пару вопросов: 1) Как в mouseMoveEvent определить потерю фокуса мыши (event->Leave почемуто действует аналогично event->Enter)? 2) Каким образом прикрутить сигнал/слот к иконке "Открыть"/"Очистить", если они выведены через painter.drawPicture Вот те исходники, над которыми я прыгал с бубном ![]() За раннее благодарю за помощь ![]() |
|
|
kwisp |
![]()
Сообщение
#2
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
XpycT,
Цитата
на сколько я знаю так делать нельзя надо тчобы на одном контексте один рисовальщик был. + зачем тебе mouseMoveEvent(QMouseEvent *event) если есть enterEvent(QEvent *event) && leaveEvent(QEvent *event) 2) Каким образом прикрутить сигнал/слот к иконке "Открыть"/"Очистить", если они выведены через painter.drawPicture вашпе не понятно что ты хочешь спросить. что значит прикрутить сигнал/слот к иконке если иконка выведена с помощью painter.drawPicture ?? Сообщение отредактировал kwisp - 20.7.2009, 18:50 |
|
|
XpycT |
![]()
Сообщение
#3
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Первый вопрос решен, спасибо.
Цитата(kwisp) вашпе не понятно что ты хочешь спросить. что значит прикрутить сигнал/слот к иконке если иконка выведена с помощью painter.drawPicture ?? Да, слабо объяснил. Я имел в виду что в paintEvent'e я добавил две иконки - на открытие нового рисунка и для очистки. CODE QImage pic_add(":/images/image_add.png"); QImage pic_del(":/images/image_delete.png"); painter.drawImage(rect().width()-pic_add.width()-25, rect().height()-35,pic_add); painter.drawImage(rect().width()-pic_add.width()-5, rect().height()-35,pic_del); Просто не пойму как к этим иконкам прикрутить вызов слотов при клике на них ![]() |
|
|
ufna |
![]()
Сообщение
#4
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 362 Регистрация: 24.5.2008 Из: Курган/СПб Пользователь №: 182 Спасибо сказали: 29 раз(а) Репутация: ![]() ![]() ![]() |
никаких слотов. Обрабатываешь эвент клика мышки, определяешь попал ли пользователь на кнопку, если да, то на какую, в зависимости от этого вызываешь нужную функцию или посылаешь сигнал, который и коннектися к какому-то слоту.
плюс - в маус мув эвенте отлавливать положение мыши на кнопке и рисовать ее другой картинкой (чтобы пользователь знал куда будет давить), и при нажатии - тоже менять картинку. но про слоты и т.п. - первый абзац. |
|
|
XpycT |
![]()
Сообщение
#5
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Как я понимаю, надо ловить координаты мыши в mousePressEvent и сравнивать, попадают ли они в координаты рисунка-кнопки в paintEvent'a, если да - вызывать действие. Ну и аналогично при движении d mouseMoveEvent для изменения состояния кнопки.
Или я не прав, и есть более простой способ? |
|
|
ufna |
![]()
Сообщение
#6
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 362 Регистрация: 24.5.2008 Из: Курган/СПб Пользователь №: 182 Спасибо сказали: 29 раз(а) Репутация: ![]() ![]() ![]() |
Да, именно так. Кстати, вызывать действие я советую только если пользователь не только нажал на кнопку мыши над этим рисунком-кнопкой, но и отпустил мышь на нем. Проверь - нормальные кнопки под винду именно так и работают. Т.е. в pressEvent ты ловишь нажал ли пользователь эту кнопку, сохраняешь себе в память данные об этом нажатии (как угодно, хоть булевой переменной и т.п.), а в releaseEvent смотришь, была ли кнопка нажата, затем проверяешь попал ли этот эвент на нужный прямоугольник, и если попал, то только тогда вызываешь действие.
а в маус муве то же самое - если кнопка уже нажата, то картинку не меняем. Если не нажата - меняем на "в фокусе" ,если мышка на картинке, а если не на картике - на "не в фокусе". я пользую у себя такой класс на данный момент:
|
|
|
XpycT |
![]()
Сообщение
#7
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
На счет опускания мыши даже не подумал.. надо будет учесть.
А вот на счет определения позиции мыши над кнопкой. Гдето в исходниках вроде как видел определение самого верхнего рисунка слоя при клике на нем, но не помню толи для пеинтера толи для график виевера, и как на зло не могу вспомнить где ![]()
Можно ли как-то таким способом определить нарисованую кнопку, а то мое условие проверки не очень радует, да и к размеру виджета привязано. Ну или на худой конец хоть упростить его ![]()
|
|
|
Litkevich Yuriy |
![]()
Сообщение
#8
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
Можно ли как-то таким способом определить нарисованую кнопку, нет, и называй вещи своими именами, тогда всё встанет на свои места. у тебя нет кнопки, у тебя есть рисунок в одной из частей которого, ты нарисовал, что-то ещё. Следовательно у тебя есть только координаты того, что ты нарисовал.Можешь после рисования куда-нибудь сохранить прямоугольник (QRect), в котором было рисование, потом воспользоваться им, что бы проверять находится ли указатель мыши внутри этого прямоугольника или нет. |
|
|
ufna |
![]()
Сообщение
#9
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 362 Регистрация: 24.5.2008 Из: Курган/СПб Пользователь №: 182 Спасибо сказали: 29 раз(а) Репутация: ![]() ![]() ![]() |
Да, лучше всего работать через QRect в данном случае. У него есть очень удобная функция для проверки принадлежности точки данному прямоугольнику.
|
|
|
XpycT |
![]()
Сообщение
#10
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Спасибо за советы, думаю разобрался
![]() |
|
|
XpycT |
![]()
Сообщение
#11
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Благодаря вашей помощи появился мой первый виджет, собственно скрин в первом посте. Реализована загрузка рисунков через QFileDialog, очистка, drag-and-drop локальных и удаленных(скачиваются в временную директорию) рисунков и запоминание пути к нему.
Делал для формы заливки на сайт - может кому и пригодится. Правда хотелось бы сделать правное "выезжание" панельки, но к сожалению в Qt еще не силен ![]() Собственно сам виджет : ![]() ЗЫ Хотел сделать плагин для дизайнера, откомпилил нормально... но при клике в панели виджетов вываливается крит. ошибка и приглашение в отладчик ![]() |
|
|
ufna |
![]()
Сообщение
#12
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 362 Регистрация: 24.5.2008 Из: Курган/СПб Пользователь №: 182 Спасибо сказали: 29 раз(а) Репутация: ![]() ![]() ![]() |
Молодец что доделал
![]() Виджет твой скачал, посмотрел. Только он не комплится в таком виде, пришлось комментарии кое где убрать ![]() Если хочешь, могу очень нудно и досконально откомментировать, т.к. есть очень много мест, над которыми нужно работать ![]() |
|
|
XpycT |
![]()
Сообщение
#13
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Молодец что доделал ![]() Виджет твой скачал, посмотрел. Только он не комплится в таком виде, пришлось комментарии кое где убрать ![]() Если хочешь, могу очень нудно и досконально откомментировать, т.к. есть очень много мест, над которыми нужно работать ![]() Я только за, ведь как еще научиться, если не на своих ошибках ![]() |
|
|
ufna |
![]()
Сообщение
#14
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 362 Регистрация: 24.5.2008 Из: Курган/СПб Пользователь №: 182 Спасибо сказали: 29 раз(а) Репутация: ![]() ![]() ![]() |
1. оформление кода. Представь, что у тебя будет не один такой файлик, а десятки, многие из которых в кучу раз длиннее. Как ты в нем ориентироваться будешь?
2. комментирование кода. Название функций, что делают, и т.д. и т.п. Т.е. код должен быть хорошо оформлен, более читабелен. Это приходит с опытом и по началу кажется излишним, но - лучше начни уделять этому внимание сейчас, потом будет куда легче. 3. Не стоит формировать виджет в main функции. Пусть это будет отдельный класс. В мейне - просто создаем что надо и делаем основную настройку приложения. 4. Сам класс. Если ты делаешь виджет, который в принципе может использоваться не в одном экземпляре и даже других проектах - он должен быть "вещью в себе", но не более чем. Грубо говоря, цель его - показывать картинку с рамочкой. А значит, он должен уметь:
Диалоговые окна из такого виджета - тоже зло. Все должно делаться через родитель, то окно, которое управляет данным виджетом. А этот виджет тогда можно было бы распространять, модифицировать под свои нужды и т.д. В таком же виде - он нужен только однажды, а переделывать.. проще написать заново, при таких размерах. Т.е. грубо говоря, нужно подходить к виджету как к немного другому функционалу, чтобы он не был "все умею, все могу". Он не должен уметь работать с сетью, зачем? А если я два десяткс таких поставлю на форму? Я говорю именно о таких вот, виджетах специализированного использование, но которые не должны делать больше, чем. А - так - молодец ![]() ![]() |
|
|
XpycT |
![]()
Сообщение
#15
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Комментариев не хватает,согласен, просто надо привыкнуть всегда их ставить
![]() На счет сигналов/слотов и ... если я тебя правильно понял, то допустим для открытия рисунка через диалог лучше в mousePressEvent просто вызвать сигнал, допустим emit imageOpen(const QString &imageName)? Хотел еще спросить на счет drag-and-drop'a .Почему, когда я использую в dragEnterEvent
ну или на худой конец
он игнорирует рисунки. Ну или как можно ограничить рисунками, чтобы другие типы файлов были запрещены(курсор перечеркнутой мыши)? Просто у меня идет проверка только после "скидывания" файла, и то по расширению. ![]() |
|
|
ufna |
![]()
Сообщение
#16
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 362 Регистрация: 24.5.2008 Из: Курган/СПб Пользователь №: 182 Спасибо сказали: 29 раз(а) Репутация: ![]() ![]() ![]() |
по сигналам - не совсем. Откуда у тебя взялось имя файла? При нажатии на кнопку ты получаешь желание его добавить изображение, т.е. можно выслать emit( imageDemand() ). А вот когда ты на виджет перетащил файл мышью из системы, то вот тогда - добавляешь на виджет, и - посылаешь emit( imageAdded(QString) ). Или можно слать указатель на картинку и т.п.
![]() А про дрэг н дроп - в dragEnterEvent сделай вывод qDebug() << event->mimeData()->formats() ![]() |
|
|
XpycT |
![]()
Сообщение
#17
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Что-то у меня со слотами не получается
![]() ![]() testApp.h
testApp.cpp
Подскажите где я ошибся ![]() |
|
|
kwisp |
![]()
Сообщение
#18
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
при чем тут слоты?
ты посмотри что написал то?
а в конструкторе
П.С. самая распространенная ошибка, если не ошибаюсь, людей только что представленных С++. ![]() Сообщение отредактировал kwisp - 22.7.2009, 15:33 |
|
|
ufna |
![]()
Сообщение
#19
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 362 Регистрация: 24.5.2008 Из: Курган/СПб Пользователь №: 182 Спасибо сказали: 29 раз(а) Репутация: ![]() ![]() ![]() |
Слот у тебя приватный, а присоединяешь его к сигналу, поступаемому от чужого класса, никак не связанного с данным. Сделай слот public.
Т.е. посмотри на мессадж выше и кое-что подправь. Сообщение отредактировал ufna - 22.7.2009, 15:33 |
|
|
kwisp |
![]()
Сообщение
#20
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Слот у тебя приватный, а присоединяешь его к сигналу, поступаемому от чужого класса, никак не связанного с данным. Сделай слот public. категорически не согласен сигналы вообще protected и нормально коннектятся. пример с приватным слотом Раскрывающийся текст
думается что спецификатор доступа влияет на вызов только при обращении на прямую не через соединение может ошибаюсь, поправьте. |
|
|
XpycT |
![]()
Сообщение
#21
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
самая распространенная ошибка, если не ошибаюсь, людей только что представленных С++. ![]() На самом деле с С++ знаком не так давно. До этого сидел только на С#, но т.к. не особо радовало Mono для linux систем, решил перейти на Qt. ![]() С сигналами всеравно не разобрался.. в дебаге вроде все прекрасно...после выбора рисунка нормально скалит, выводит зум и путь к рисунку.
но рисунок не появляется, и следующий вывод i_fileName возвращает пустую строку. Пришел к тому с чего начал - вернул диалог обратно в виджет, хоть так работает ![]() |
|
|
Litkevich Yuriy |
![]()
Сообщение
#22
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
Слот у тебя приватный, а присоединяешь его к сигналу, поступаемому от чужого класса, никак не связанного с данным. Сделай слот public. он соеденяет со своим (this) слотом, который этим (this) классом видится. А а сигнал виден всегда, если виден объект.при чем тут слоты? угу
ты посмотри что написал то? |
|
|
kwisp |
![]()
Сообщение
#23
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
XpycT,
С сигналами всеравно не разобрался.. не понял тебя. на всякий случай напишу. ты сделал класс членами которого являются ImageWidget screen1,screen2. Заметь это не указатели а объекты. при вызове конструктора класса они благополучно инициализируются в списке инициализации конструкторами по умолчанию(хоть ты их и не трогаешь явно с++ это делает за тебя) за тем ты зачем не ясно объявляешь( и инициализируешь из кучи) в конструкторе локальные переменные указетели одноименные с твоими объектами класса ImageWidget* screen1, *screen2. потом вообще весело ты соединяешь сигнал одного локально видимого динамически созданного обекта screen1 с каким то слотом(не важно каким) надеясь что вызовется сигнал. ![]() вариантов поправить эту ошибку много один из вариантов будет таким:
пробуй теперь. здесь я оставил объекты ImageWidget как есть а вообще тролли настоятельно рекомендуют создавать виджеты динамически. Сообщение отредактировал kwisp - 22.7.2009, 17:10 |
|
|
ufna |
![]()
Сообщение
#24
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 362 Регистрация: 24.5.2008 Из: Курган/СПб Пользователь №: 182 Спасибо сказали: 29 раз(а) Репутация: ![]() ![]() ![]() |
Цитата категорически не согласен сигналы вообще protected и нормально коннектятся. пример с приватным слотом ты сам мне приводишь пример, где Sender - член класса Rec. В конструкторе же у Хруста создается новый объект, никак не связанный с изначальным классом: ImageWidget *screen1=new ImageWidget; И соединяет он этот screen1, а не TestApp::screen1. И доступа к приватному слоту у этого объекта быть не должно. дополнение: про this понял Сообщение отредактировал ufna - 22.7.2009, 16:56 |
|
|
kwisp |
![]()
Сообщение
#25
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
ufna,
не пойму тебя приведи свой пример. вот мой модифицированный Раскрывающийся текст
или так Раскрывающийся текст
что теперь скажете? П.С. что то я сегодня плохо понимаю. пойду на пляж в волейбол играть. Сообщение отредактировал kwisp - 22.7.2009, 17:04 |
|
|
ufna |
![]()
Сообщение
#26
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 362 Регистрация: 24.5.2008 Из: Курган/СПб Пользователь №: 182 Спасибо сказали: 29 раз(а) Репутация: ![]() ![]() ![]() |
kwisp, сорри, тупил. После поста Юрия в доки глянул, понял.
Как то всегда руководствовался правилом - private slot - для внутренних объектов, public slot - для внешних. Изначально как понял, так и делал. Блин ) Сообщение отредактировал ufna - 22.7.2009, 17:18 |
|
|
kwisp |
![]()
Сообщение
#27
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
ufna,
принимается. со всяким бывает. |
|
|
ufna |
![]()
Сообщение
#28
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 362 Регистрация: 24.5.2008 Из: Курган/СПб Пользователь №: 182 Спасибо сказали: 29 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
XpycT |
![]()
Сообщение
#29
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
твою ж... точно не правильно виджеты создал. Вот что значит невнимательность.
![]() Вот только хотел спросить , как правельнее создать одинаковые QObject::connect'ы перебором, если у меня допустим их штук 20. Ведь как я понимаю - не правильно будет их дублировать типа
видел макросы типа qobject_cast, qvariant_cast... но не совсем понял как ими пользоваться |
|
|
Litkevich Yuriy |
![]()
Сообщение
#30
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
XpycT, для случая разных отправителей, лучше используй "карту сигналов" QSignalMaper, я где-то пример на форуме давал, да и в Асистенте он описан достаточно.
П.С. или "отображатель сигналов", или "перенаправитель сигналов", или "коллектор сигналов" не знаю как лучше сказать |
|
|
XpycT |
![]()
Сообщение
#31
|
![]() Студент ![]() Группа: Участник Сообщений: 43 Регистрация: 7.7.2009 Пользователь №: 883 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 16.7.2025, 20:42 |