crossplatform.ru

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

4 страниц V   1 2 3 > »   
Ответить в данную темуНачать новую тему
XpycT
  опции профиля:
сообщение 20.7.2009, 17:51
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   0  


Всем доброго времени суток :)
С Qt знаком всего полторы недели, и то, все это время читал книги. Вот захотелось реализовать виджет выбора рисунка (не хочется делать просто текстовое поле с адресом). За основу взял исходники примера с гита Qt. Но к моему сожалению понял, что прочитанных разделов о графике в книгах не достаточно :(.

Хочется сделать что-то типа такого :
 Р В Р’ Р’ Р’ Р в‚¬Р В РЎВ˜Р В Р’µР Р…ьшено Р Т‘Р С• 35%
Прикрепленное изображение
405 x 441 (38.52 килобайт)


Но напоролся на пару вопросов:

1) Как в mouseMoveEvent определить потерю фокуса мыши (event->Leave почемуто действует аналогично event->Enter)?
2) Каким образом прикрутить сигнал/слот к иконке "Открыть"/"Очистить", если они выведены через painter.drawPicture

Вот те исходники, над которыми я прыгал с бубном Прикрепленный файл  imagewidget.zip ( 2.48 килобайт ) Кол-во скачиваний: 189


За раннее благодарю за помощь :rolleyes:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 20.7.2009, 18:52
Сообщение #2


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

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




Репутация:   23  


XpycT,
Цитата
void ImageWidget::paintEvent(QPaintEvent*)
{


    QPainter painter(this);
    QPainter painter1(this);
...


на сколько я знаю так делать нельзя
надо тчобы на одном контексте один рисовальщик был.

+

зачем тебе mouseMoveEvent(QMouseEvent *event)
если есть enterEvent(QEvent *event) && leaveEvent(QEvent *event)

Цитата(XpycT @ 20.7.2009, 18:51) *
2) Каким образом прикрутить сигнал/слот к иконке "Открыть"/"Очистить", если они выведены через painter.drawPicture

вашпе не понятно что ты хочешь спросить. что значит прикрутить сигнал/слот к иконке если иконка выведена с помощью painter.drawPicture ??

Сообщение отредактировал kwisp - 20.7.2009, 18:50
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
XpycT
  опции профиля:
сообщение 20.7.2009, 20:44
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   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
  опции профиля:
сообщение 20.7.2009, 20:54
Сообщение #4


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

Группа: Участник
Сообщений: 362
Регистрация: 24.5.2008
Из: Курган/СПб
Пользователь №: 182

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




Репутация:   5  


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

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

но про слоты и т.п. - первый абзац.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
XpycT
  опции профиля:
сообщение 20.7.2009, 22:07
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   0  


Как я понимаю, надо ловить координаты мыши в mousePressEvent и сравнивать, попадают ли они в координаты рисунка-кнопки в paintEvent'a, если да - вызывать действие. Ну и аналогично при движении d mouseMoveEvent для изменения состояния кнопки.

Или я не прав, и есть более простой способ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ufna
  опции профиля:
сообщение 20.7.2009, 22:52
Сообщение #6


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

Группа: Участник
Сообщений: 362
Регистрация: 24.5.2008
Из: Курган/СПб
Пользователь №: 182

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




Репутация:   5  


Да, именно так. Кстати, вызывать действие я советую только если пользователь не только нажал на кнопку мыши над этим рисунком-кнопкой, но и отпустил мышь на нем. Проверь - нормальные кнопки под винду именно так и работают. Т.е. в pressEvent ты ловишь нажал ли пользователь эту кнопку, сохраняешь себе в память данные об этом нажатии (как угодно, хоть булевой переменной и т.п.), а в releaseEvent смотришь, была ли кнопка нажата, затем проверяешь попал ли этот эвент на нужный прямоугольник, и если попал, то только тогда вызываешь действие.

а в маус муве то же самое - если кнопка уже нажата, то картинку не меняем. Если не нажата - меняем на "в фокусе" ,если мышка на картинке, а если не на картике - на "не в фокусе".

я пользую у себя такой класс на данный момент:
//-----------------------------------------------------------------------------
// File: a_cupics_layoutbutton.h
//
// Desc:
//-----------------------------------------------------------------------------

#ifndef A_CUPICS_LAYOUTBUTTON_H
#define A_CUPICS_LAYOUTBUTTON_H

#include <QObject>
#include <QPixmap>
#include <QRect>

//--------------------------------------------------------------------------------------
// Name: cUPicsLayoutButton
// Desc:
//--------------------------------------------------------------------------------------
class cUPicsLayoutButton
    : public QObject
{
    Q_OBJECT

public:
    // Constructor & destructor
    //----------------------------------------------------------------------------------
    cUPicsLayoutButton(QPixmap pxm, QObject *parent = 0);

    // Enums & others
    //----------------------------------------------------------------------------------
    enum State { Normal, Pressed, Hot };

    // Access functions
    //----------------------------------------------------------------------------------
    QPixmap getView() const;

    QRect rect() { return m_btnRect; }
    int state() const { return m_btnState; }

    // Control functions
    //----------------------------------------------------------------------------------
    void setRect(QRect rect) { m_btnRect = rect; }
    void setState(State s) { m_btnState = s; }
    void setPixmap(QPixmap pxm, State s = Normal);

private:
    // Page paint data
    //----------------------------------------------------------------------------------
    QRect m_btnRect;
    State m_btnState;

    QPixmap m_pxmNormal,
            m_pxmPressed,
            m_pxmHot;

};
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
XpycT
  опции профиля:
сообщение 21.7.2009, 0:20
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   0  


На счет опускания мыши даже не подумал.. надо будет учесть.

А вот на счет определения позиции мыши над кнопкой.
Гдето в исходниках вроде как видел определение самого верхнего рисунка слоя при клике на нем, но не помню толи для пеинтера толи для график виевера, и как на зло не могу вспомнить где :( . Строка была чтото вроде
qobject_cast<const тип*>(sender)

Можно ли как-то таким способом определить нарисованую кнопку, а то мое условие проверки не очень радует, да и к размеру виджета привязано. Ну или на худой конец хоть упростить его :)
void ImageWidget::mouseMoveEvent(QMouseEvent *event)
{
    mousePos = event->pos();
    if((mousePos.x() > (rect().width()-pic_add.width()-25)) &
       (mousePos.x() < (rect().width()-25))    &
       (mousePos.y() > (rect().height()-22))   &
       (mousePos.y() < (rect().height()-6)))
    {
        setCursor(Qt::PointingHandCursor);
        setButton(Open);
    }else if((mousePos.x() > (rect().width()-pic_del.width()-5)) &
       (mousePos.x() < (rect().width()-5))    &
       (mousePos.y() > (rect().height()-22))   &
       (mousePos.y() < (rect().height()-6)))
    {
        setCursor(Qt::PointingHandCursor);
        setButton(Clear);
    }else{        
        setCursor(Qt::ArrowCursor);
        setButton(None);
    }
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 21.7.2009, 4:11
Сообщение #8


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


Цитата(XpycT @ 21.7.2009, 4:20) *
Можно ли как-то таким способом определить нарисованую кнопку,
нет, и называй вещи своими именами, тогда всё встанет на свои места. у тебя нет кнопки, у тебя есть рисунок в одной из частей которого, ты нарисовал, что-то ещё. Следовательно у тебя есть только координаты того, что ты нарисовал.
Можешь после рисования куда-нибудь сохранить прямоугольник (QRect), в котором было рисование, потом воспользоваться им, что бы проверять находится ли указатель мыши внутри этого прямоугольника или нет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ufna
  опции профиля:
сообщение 21.7.2009, 7:56
Сообщение #9


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

Группа: Участник
Сообщений: 362
Регистрация: 24.5.2008
Из: Курган/СПб
Пользователь №: 182

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




Репутация:   5  


Да, лучше всего работать через QRect в данном случае. У него есть очень удобная функция для проверки принадлежности точки данному прямоугольнику.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
XpycT
  опции профиля:
сообщение 21.7.2009, 8:15
Сообщение #10


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   0  


Спасибо за советы, думаю разобрался :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
XpycT
  опции профиля:
сообщение 21.7.2009, 20:40
Сообщение #11


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   0  


Благодаря вашей помощи появился мой первый виджет, собственно скрин в первом посте. Реализована загрузка рисунков через QFileDialog, очистка, drag-and-drop локальных и удаленных(скачиваются в временную директорию) рисунков и запоминание пути к нему.
Делал для формы заливки на сайт - может кому и пригодится. Правда хотелось бы сделать правное "выезжание" панельки, но к сожалению в Qt еще не силен :)

Собственно сам виджет : Прикрепленный файл  imagewidget.zip ( 5.79 килобайт ) Кол-во скачиваний: 154


ЗЫ Хотел сделать плагин для дизайнера, откомпилил нормально... но при клике в панели виджетов вываливается крит. ошибка и приглашение в отладчик :(
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ufna
  опции профиля:
сообщение 21.7.2009, 21:05
Сообщение #12


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

Группа: Участник
Сообщений: 362
Регистрация: 24.5.2008
Из: Курган/СПб
Пользователь №: 182

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




Репутация:   5  


Молодец что доделал :)

Виджет твой скачал, посмотрел. Только он не комплится в таком виде, пришлось комментарии кое где убрать :)

Если хочешь, могу очень нудно и досконально откомментировать, т.к. есть очень много мест, над которыми нужно работать :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
XpycT
  опции профиля:
сообщение 21.7.2009, 21:21
Сообщение #13


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   0  


Цитата(ufna @ 21.7.2009, 21:05) *
Молодец что доделал :)

Виджет твой скачал, посмотрел. Только он не комплится в таком виде, пришлось комментарии кое где убрать :)

Если хочешь, могу очень нудно и досконально откомментировать, т.к. есть очень много мест, над которыми нужно работать :)


Я только за, ведь как еще научиться, если не на своих ошибках :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ufna
  опции профиля:
сообщение 21.7.2009, 22:44
Сообщение #14


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

Группа: Участник
Сообщений: 362
Регистрация: 24.5.2008
Из: Курган/СПб
Пользователь №: 182

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




Репутация:   5  


1. оформление кода. Представь, что у тебя будет не один такой файлик, а десятки, многие из которых в кучу раз длиннее. Как ты в нем ориентироваться будешь?
2. комментирование кода. Название функций, что делают, и т.д. и т.п.

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

3. Не стоит формировать виджет в main функции. Пусть это будет отдельный класс. В мейне - просто создаем что надо и делаем основную настройку приложения.

4. Сам класс. Если ты делаешь виджет, который в принципе может использоваться не в одном экземпляре и даже других проектах - он должен быть "вещью в себе", но не более чем. Грубо говоря, цель его - показывать картинку с рамочкой. А значит, он должен уметь:
  • Принимать в себя картинку из внешнего пространства
  • Отображать ее
  • Удалять ее из себя
  • Посылать сигналы: картинка добавлена, картинка удалена, и - очень важно - сигнал-запрос на добавление картинки.


Диалоговые окна из такого виджета - тоже зло. Все должно делаться через родитель, то окно, которое управляет данным виджетом. А этот виджет тогда можно было бы распространять, модифицировать под свои нужды и т.д. В таком же виде - он нужен только однажды, а переделывать.. проще написать заново, при таких размерах.

Т.е. грубо говоря, нужно подходить к виджету как к немного другому функционалу, чтобы он не был "все умею, все могу". Он не должен уметь работать с сетью, зачем? А если я два десяткс таких поставлю на форму?

Я говорю именно о таких вот, виджетах специализированного использование, но которые не должны делать больше, чем.

А - так - молодец :) Работай дальше, изучай программирование и Qt, и опыт появится. Главное, самое главное - хорошо оформляй код. Делай его читаемым и структурированым. Это позволит видеть свои ошибки в дальнейшем куда быстрее :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
XpycT
  опции профиля:
сообщение 22.7.2009, 8:48
Сообщение #15


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   0  


Комментариев не хватает,согласен, просто надо привыкнуть всегда их ставить :)
На счет сигналов/слотов и ... если я тебя правильно понял, то допустим для открытия рисунка через диалог лучше в mousePressEvent просто вызвать сигнал, допустим emit imageOpen(const QString &imageName)?

Хотел еще спросить на счет drag-and-drop'a .Почему, когда я использую в dragEnterEvent
if(event->mimeData()->hasImage())

ну или на худой конец
if (event->mimeData()->hasFormat("image/jpeg") && ...)

он игнорирует рисунки. Ну или как можно ограничить рисунками, чтобы другие типы файлов были запрещены(курсор перечеркнутой мыши)? Просто у меня идет проверка только после "скидывания" файла, и то по расширению. :(
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ufna
  опции профиля:
сообщение 22.7.2009, 9:06
Сообщение #16


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

Группа: Участник
Сообщений: 362
Регистрация: 24.5.2008
Из: Курган/СПб
Пользователь №: 182

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




Репутация:   5  


по сигналам - не совсем. Откуда у тебя взялось имя файла? При нажатии на кнопку ты получаешь желание его добавить изображение, т.е. можно выслать emit( imageDemand() ). А вот когда ты на виджет перетащил файл мышью из системы, то вот тогда - добавляешь на виджет, и - посылаешь emit( imageAdded(QString) ). Или можно слать указатель на картинку и т.п. :)


А про дрэг н дроп - в dragEnterEvent сделай вывод qDebug() << event->mimeData()->formats() :) Там увидишь какие форматы и что шлет тебе систем. Я на память не помню. Так когда из системы перетаскиваешь, будет не картика, а путь к ней, если не ошибаюсь.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
XpycT
  опции профиля:
сообщение 22.7.2009, 15:19
Сообщение #17


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   0  


Что-то у меня со слотами не получается :( в виджете на клик по рисунку "открыть" поставил emit imageBrowse();. в форме приложения прикрутил сигнал, но после выбора рисунок не открывается и путь к нему пустой :( Хотя если диалог открытия в самом виджете - все работает. Делал так :
testApp.h
#ifndef TESTAPP_H
#define TESTAPP_H

#include <QDialog>
#include "ImageWidget.h"
class TestApp : public QDialog
{
    Q_OBJECT

public:
    TestApp(QWidget *parent=0);
private slots:
    void openImage();
private:
    ImageWidget screen1;
    ImageWidget screen2;
};

#endif // TESTAPP_H

testApp.cpp
#include <QtGui>
#include "testapp.h"
#include "ImageWidget.h"

TestApp::TestApp(QWidget *parent)
        :QDialog(parent)
{
    ImageWidget *screen1=new ImageWidget;    
    ImageWidget *screen2=new ImageWidget;  
    screen2->loadImage("D:\\21.jpg"); // <<< Если на прямую с конструктора - все работает прекрасно.
    QHBoxLayout *layout =new QHBoxLayout;
    layout->addWidget(screen1);
    layout->addWidget(screen2);
    setLayout(layout);

    connect(screen1,SIGNAL(imageBrowse()),this,SLOT(openImage()));

}
void TestApp::openImage()
{    
    QString fileName = QFileDialog::getOpenFileName(this,tr("Select Image"),
                                       QApplication::applicationDirPath(),
                                       tr("Image Files (*.jpg *.jpeg *.png *.bmp *.gif)"));

          if(fileName.isEmpty())
            return;
          else
              screen1.loadImage(fileName);
}


Подскажите где я ошибся :mellow:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 22.7.2009, 15:30
Сообщение #18


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

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




Репутация:   23  


при чем тут слоты?
ты посмотри что написал то?

...
private:
    ImageWidget screen1;
    ImageWidget screen2;
...

а в конструкторе
...
 ImageWidget *screen1=new ImageWidget;    
    ImageWidget *screen2=new ImageWidget;  
....


П.С.
самая распространенная ошибка, если не ошибаюсь, людей только что представленных С++. :)

Сообщение отредактировал kwisp - 22.7.2009, 15:33
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ufna
  опции профиля:
сообщение 22.7.2009, 15:32
Сообщение #19


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

Группа: Участник
Сообщений: 362
Регистрация: 24.5.2008
Из: Курган/СПб
Пользователь №: 182

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




Репутация:   5  


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

Т.е. посмотри на мессадж выше и кое-что подправь.

Сообщение отредактировал ufna - 22.7.2009, 15:33
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 22.7.2009, 15:51
Сообщение #20


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

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




Репутация:   23  


Цитата(ufna @ 22.7.2009, 16:32) *
Слот у тебя приватный, а присоединяешь его к сигналу, поступаемому от чужого класса, никак не связанного с данным. Сделай слот public.

категорически не согласен
сигналы вообще protected и нормально коннектятся.
пример с приватным слотом
Раскрывающийся текст
#ifndef _R_
#define _R_

#include <QObject>
#include <QtDebug>
#include <QtGlobal>

class Sender: public QObject
{
    Q_OBJECT
public:
        Sender(QObject* par=0):QObject(par){ startTimer(1000);}
signals:
        void sg(); 
protected:
    void timerEvent(QTimerEvent*)
    {
        emit sg();
    }
};

class Rec: public QObject
{
    Q_OBJECT
public:
        Rec(QObject* par=0):QObject(par)
        {
            
            sender__ = new Sender;
            connect(sender__,SIGNAL(sg()),this,SLOT(sl()));
        }
private slots:
    void sl(){ qDebug()<<__func__;}

private:
    Sender* sender__;
};

#endif //_R_


думается что спецификатор доступа влияет на вызов только при обращении на прямую не через соединение
может ошибаюсь, поправьте.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
XpycT
  опции профиля:
сообщение 22.7.2009, 16:40
Сообщение #21


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   0  


Цитата(kwisp @ 22.7.2009, 15:30) *
самая распространенная ошибка, если не ошибаюсь, людей только что представленных С++. :)


На самом деле с С++ знаком не так давно. До этого сидел только на С#, но т.к. не особо радовало Mono для linux систем, решил перейти на Qt. :)

С сигналами всеравно не разобрался.. в дебаге вроде все прекрасно...после выбора рисунка нормально скалит, выводит зум и путь к рисунку.
Rescaling image.... 
[Zoom 113%] "C:\Documents and Settings\XpycTои документы\404.jpg" 
i_fileName = C:\Documents and Settings\XpycT\Мои документы\404.jpg

но рисунок не появляется, и следующий вывод i_fileName возвращает пустую строку.

Пришел к тому с чего начал - вернул диалог обратно в виджет, хоть так работает :unsure:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.7.2009, 16:52
Сообщение #22


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


Цитата(ufna @ 22.7.2009, 19:32) *
Слот у тебя приватный, а присоединяешь его к сигналу, поступаемому от чужого класса, никак не связанного с данным. Сделай слот public.
он соеденяет со своим (this) слотом, который этим (this) классом видится. А а сигнал виден всегда, если виден объект.

Цитата(kwisp @ 22.7.2009, 19:30) *
при чем тут слоты?
ты посмотри что написал то?
угу
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 22.7.2009, 16:54
Сообщение #23


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

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




Репутация:   23  


XpycT,
Цитата(XpycT @ 22.7.2009, 17:40) *
С сигналами всеравно не разобрался..

не понял тебя.
на всякий случай напишу.
ты сделал класс членами которого являются ImageWidget screen1,screen2. Заметь это не указатели а объекты.

при вызове конструктора класса они благополучно инициализируются в списке инициализации конструкторами по умолчанию(хоть ты их и не трогаешь явно с++ это делает за тебя)
за тем ты зачем не ясно объявляешь( и инициализируешь из кучи) в конструкторе локальные переменные указетели одноименные с твоими объектами класса ImageWidget* screen1, *screen2.

потом вообще весело ты соединяешь сигнал одного локально видимого динамически созданного обекта screen1 с каким то слотом(не важно каким) надеясь что вызовется сигнал.:)

вариантов поправить эту ошибку много
один из вариантов будет таким:
#include <QtGui>
#include "testapp.h"
#include "ImageWidget.h"

TestApp::TestApp(QWidget *parent)
        :QDialog(parent)
{
    //screen2->loadImage("D:\\21.jpg"); // <<< Если на прямую с конструктора - все работает прекрасно.
    QHBoxLayout *layout =new QHBoxLayout;
    layout->addWidget(&screen1);
    layout->addWidget(&screen2);
    setLayout(layout);

    connect(&screen1,SIGNAL(imageBrowse()),this,SLOT(openImage()));

}
void TestApp::openImage()
{    
    QString fileName = QFileDialog::getOpenFileName(this,tr("Select Image"),
                                       QApplication::applicationDirPath(),
                                       tr("Image Files (*.jpg *.jpeg *.png *.bmp *.gif)"));

          if(fileName.isEmpty())
            return;
          else
              screen1.loadImage(fileName);
}



пробуй теперь.
здесь я оставил объекты ImageWidget как есть а вообще тролли настоятельно рекомендуют создавать виджеты динамически.

Сообщение отредактировал kwisp - 22.7.2009, 17:10
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ufna
  опции профиля:
сообщение 22.7.2009, 16:54
Сообщение #24


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

Группа: Участник
Сообщений: 362
Регистрация: 24.5.2008
Из: Курган/СПб
Пользователь №: 182

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




Репутация:   5  


Цитата
категорически не согласен
сигналы вообще protected и нормально коннектятся.
пример с приватным слотом


ты сам мне приводишь пример, где Sender - член класса Rec. В конструкторе же у Хруста создается новый объект, никак не связанный с изначальным классом: ImageWidget *screen1=new ImageWidget;
И соединяет он этот screen1, а не TestApp::screen1. И доступа к приватному слоту у этого объекта быть не должно.


дополнение:
про this понял

Сообщение отредактировал ufna - 22.7.2009, 16:56
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 22.7.2009, 16:58
Сообщение #25


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

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




Репутация:   23  


ufna,
не пойму тебя

приведи свой пример.
вот мой модифицированный
Раскрывающийся текст
    #ifndef _R_
    #define _R_

    #include <QObject>
    #include <QtDebug>
    #include <QtGlobal>

    class Sender: public QObject
    {
        Q_OBJECT
    public:
            Sender(QObject* par=0):QObject(par){ startTimer(1000);}
    signals:
            void sg(); 
    protected:
        void timerEvent(QTimerEvent*)
        {
            emit sg();
        }
    };

    class Rec: public QObject
    {
        Q_OBJECT
    public:
            Rec(QObject* par=0):QObject(par)
            {
                
                Sender* sender__ = new Sender;
                connect(sender__,SIGNAL(sg()),this,SLOT(sl()));
            }
    private slots:
        void sl(){ qDebug()<<__func__;}
    };

    #endif //_R_

или так
Раскрывающийся текст

    #ifndef _R_
    #define _R_

    #include <QObject>
    #include <QtDebug>
    #include <QtGlobal>

    class Sender: public QObject
    {
        Q_OBJECT
    public:
            Sender(QObject* par=0):QObject(par){ startTimer(1000);}
    signals:
            void sg(); 
    protected:
        void timerEvent(QTimerEvent*)
        {
            emit sg();
        }
    };

    class Rec: public QObject
    {
        Q_OBJECT
    public:
            Rec(QObject* par=0):QObject(par)
            {
                
//                Sender* sender__ = new Sender;
//                connect(sender__,SIGNAL(sg()),this,SLOT(sl()));
            }
    Sender* CreateSender(){return new Sender;};
    private slots:
        void sl(){ qDebug()<<__func__;}
    };

    #endif //_R_
////
файл main.cpp
////
#include <QApplication>
#include "rec.h"
int main(int a,char** b)
{
    QApplication app(a,b);
    Rec rec;
    Sender* sender__ = rec.CreateSender();
    QObject::connect(sender__,SIGNAL(sg()),&rec,SLOT(sl()));
    return app.exec();
}


что теперь скажете?

П.С.
что то я сегодня плохо понимаю.
пойду на пляж в волейбол играть.

Сообщение отредактировал kwisp - 22.7.2009, 17:04
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ufna
  опции профиля:
сообщение 22.7.2009, 17:15
Сообщение #26


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

Группа: Участник
Сообщений: 362
Регистрация: 24.5.2008
Из: Курган/СПб
Пользователь №: 182

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




Репутация:   5  


kwisp, сорри, тупил. После поста Юрия в доки глянул, понял.

Как то всегда руководствовался правилом - private slot - для внутренних объектов, public slot - для внешних. Изначально как понял, так и делал. Блин )

Сообщение отредактировал ufna - 22.7.2009, 17:18
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 22.7.2009, 17:23
Сообщение #27


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

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




Репутация:   23  


ufna,
принимается.
со всяким бывает.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ufna
  опции профиля:
сообщение 22.7.2009, 17:24
Сообщение #28


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

Группа: Участник
Сообщений: 362
Регистрация: 24.5.2008
Из: Курган/СПб
Пользователь №: 182

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




Репутация:   5  


Цитата(XpycT @ 22.7.2009, 17:40) *
Пришел к тому с чего начал - вернул диалог обратно в виджет, хоть так работает :unsure:


Лучше доразберись. Изначально поправь конструктор. Потом если все так и не идет, дай код, может еще куда что нить забралось.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
XpycT
  опции профиля:
сообщение 22.7.2009, 17:52
Сообщение #29


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   0  


твою ж... точно не правильно виджеты создал. Вот что значит невнимательность. :( Спасибо все работает.

Вот только хотел спросить , как правельнее создать одинаковые QObject::connect'ы перебором, если у меня допустим их штук 20. Ведь как я понимаю - не правильно будет их дублировать типа
connect(screen1,SIGNAL(imageBrowse()),this,SLOT(openImage()));
    connect(screen...,SIGNAL(imageBrowse()),this,SLOT(openImage()));
    connect(screen20,SIGNAL(imageBrowse()),this,SLOT(openImage()));

видел макросы типа qobject_cast, qvariant_cast... но не совсем понял как ими пользоваться
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.7.2009, 18:16
Сообщение #30


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


XpycT, для случая разных отправителей, лучше используй "карту сигналов" QSignalMaper, я где-то пример на форуме давал, да и в Асистенте он описан достаточно.

П.С. или "отображатель сигналов", или "перенаправитель сигналов", или "коллектор сигналов" не знаю как лучше сказать
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
XpycT
  опции профиля:
сообщение 22.7.2009, 18:43
Сообщение #31


Студент
*

Группа: Участник
Сообщений: 43
Регистрация: 7.7.2009
Пользователь №: 883

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




Репутация:   0  


Цитата(Litkevich Yuriy @ 22.7.2009, 18:16) *
XpycT, для случая разных отправителей, лучше используй "карту сигналов" QSignalMaper...

Спасибо, добавил в закладки .
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 16.7.2025, 20:42