Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: yuraborodin от Ноябрь 12, 2009, 03:24



Название: собственный виджет
Отправлено: yuraborodin от Ноябрь 12, 2009, 03:24
Доброе утро, форум!
Странная проблема.
Написал свой виджет.
Вставил его при помощи дизайнера методом продвижения (promoted).
На форме разместил 2 таких виджета.
Но работает только один виджет. А второй нет. Долго не мог понять, в чем проблема.
Потом подумал, что виджет может быть уникальным только внутри одного родителя.
Тогда я их разместил в разных родителях-виджетах:первый виджет оставил как есть, а второй запихал в новый QWidget.И все работает. Вопрос - почему так? И как это решить правильно?
Спасибо.


Название: Re: собственный виджет
Отправлено: Alex Custov от Ноябрь 12, 2009, 03:31
всё дело в волшебных пузырьках.

Лучше код приложи, и опиши подробнее что за виджеты и что значит "не работает".


Название: Re: собственный виджет
Отправлено: yuraborodin от Ноябрь 12, 2009, 03:37
Виджет IplImageWidget для вывода изображения с картинки типа IplImage (из библиотеки OpenCV  (компьютерное зрение))
Код:
class IplImageWidget : public QWidget
{
    Q_OBJECT
public:
    IplImageWidget(QWidget* parent = 0, Qt::WFlags fl = 0 );
    ~IplImageWidget();
    void initWidget(CvCapture* video);
    void PutImage(IplImage* img);
protected:
    void paintEvent(QPaintEvent*);   
private:
    QImage qimage;
    QImage qimage1;
    IplImage* opencvimg;
    IplImage* opencvimg1;
};

IplImageWidget::IplImageWidget(QWidget* parent, Qt::WFlags fl)
: QWidget(parent, fl)
{}

IplImageWidget::~IplImageWidget()
{}

void IplImageWidget::initWidget(CvCapture* video)
{
    double h=cvGetCaptureProperty(video,CV_CAP_PROP_FRAME_HEIGHT);
    double w=cvGetCaptureProperty(video,CV_CAP_PROP_FRAME_WIDTH);
    qimage = QImage(QSize(w,h), QImage::Format_RGB888);
    qimage1 = QImage(QSize(w,h), QImage::Format_RGB888);
    opencvimg = cvCreateImageHeader(cvSize(qimage.width(),qimage.height()),8,3);
    opencvimg1 = cvCreateImageHeader(cvSize(qimage1.width(),qimage1.height()),8,1);
    opencvimg->imageData = (char*)qimage.bits();
    opencvimg1->imageData = (char*)qimage1.bits();
}

void IplImageWidget::PutImage(IplImage* img)
{
    if(img->nChannels==1)
    {
        cvCopy(img, opencvimg1, 0);
        cvCvtColor(opencvimg1,opencvimg,CV_GRAY2RGB);
    }
    else if(img->nChannels==3)
    {
        cvCopy(img, opencvimg, 0);
        cvCvtColor(opencvimg,opencvimg,CV_BGR2RGB);
    }
}

void IplImageWidget::paintEvent(QPaintEvent*)
{
    QPainter painter(this);   
    if(!qimage.isNull())
        painter.drawImage(QPoint(x(),y()), qimage.scaled(QSize(width(),height())));
}

и код ниже, который посылает картинку в виджет:

Код:
....
 ui->wFrames->initWidget(video);
....
    IplImage *originalImg=cvQueryFrame(video);   
    if(originalImg)
    {
        ui->wFrames->PutImage(originalImg);
    }
    .....
Вышеописанный код работает - картинка выводится.
Но если я вместо wFrames напишу wFrames2 - то картинка не будет выводиться.


Название: Re: собственный виджет
Отправлено: yuraborodin от Ноябрь 12, 2009, 15:46
попробовал по другому:
Код:
MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{
   top = new IplImageWidget;
   bottom = new IplImageWidget;  
   play = new QPushButton("Play");        
   QVBoxLayout* vLayout = new QVBoxLayout;
   vLayout->addWidget(top);
   vLayout->addWidget(bottom);
   vLayout->addWidget(play);
   setLayout(vLayout);
   connect(play,SIGNAL(clicked()),this,SLOT(on_play_clicked()));
}

виджет bottom не оторбражается.

переделываю так:
 
Код:
top = new IplImageWidget;   
QWidget* parentWidget = new QWidget;
bottom = new IplImageWidget(parentWidget);  
play = new QPushButton("Play");
QVBoxLayout* vLayout = new QVBoxLayout;
vLayout->addWidget(top);
vLayout->addWidget(parentWidget);
vLayout->addWidget(play);
setLayout(vLayout);

тогда отображается.
Вопрос: почему я не могу располагать 2 виджета одинакового типа в одном родительском виджете???
Такое впечатление, что класс виджета IplImageWidget не дописан или неправильно определен.
Код:
class IplImageWidget : public QWidget
{
    Q_OBJECT
public:
    IplImageWidget(QWidget* parent = 0, Qt::WFlags fl = 0 );
    ~IplImageWidget();
    void initWidget(CvCapture* video);
    void PutImage(IplImage* img);
protected:
    void paintEvent(QPaintEvent*);   
private:
    QImage qimage;
    QImage qimage1;
    IplImage* opencvimg;
    IplImage* opencvimg1;
};