PDA

View Full Version : QGridLayout refresh



Pawello
6th August 2012, 13:36
Hi, I'm trying to change grid layout in one of the GroupBoxes, where layout depends on option chosen in Combobox. Here is shortened version of my program. funcion AktualA should change layout in groupBox dane, but this works only with first change of Combobox. Thanks for help

nowywpis.h


#ifndef NOWYWPIS_H
#define NOWYWPIS_H
#include <QWidget>
#include <QGridLayout>
#include <QComboBox>
QT_BEGIN_NAMESPACE
class QGroupBox;
class QComboBox;
QT_END_NAMESPACE

class NowyWpis : public QWidget
{
Q_OBJECT
public:
NowyWpis(QWidget *parent = 0);
private slots:
void AktualA();
void AktualT();
private:
void WyborT();
QGroupBox *wybort;
QGroupBox *dane;
QComboBox *wybierzt;
};
#endif // NOWYWPIS_H

nowywpis.cpp

#include <QtGui>
#include "nowywpis.h"
NowyWpis::NowyWpis(QWidget *parent)
: QWidget(parent)
{
WyborT();
}
void NowyWpis::WyborT()
{
QVBoxLayout *Layout = new QVBoxLayout;
wybort = new QGroupBox(tr("Wybor T"));
dane = new QGroupBox(tr("Dane"));
QGridLayout *grid = new QGridLayout;
wybierzt = new QComboBox;
…
connect(wybierzt, SIGNAL(currentIndexChanged(int)),
this, SLOT(AktualT()));
connect(wybierzt, SIGNAL(currentIndexChanged(int)),
this, SLOT(AktualA()));
…
grid->addWidget(wybierzt, 0, 0);
wybort->setLayout(grid);
Layout->addWidget(wybort);
Layout->addWidget(dane);
setLayout(Layout);
setWindowTitle(tr("Dodaj nowy wpis"));
resize(800, 600);
}

void NowyWpis::AktualT()
{
wybranyt =(wybierzt->currentText());
}

void NowyWpis::AktualA()
{

QGridLayout *siatka = new QGridLayout;
…
dane->setLayout(siatka);
}

ChrisW67
7th August 2012, 02:23
What about it doesn't work? How do you know it isn't working?

Pawello
7th August 2012, 10:04
When I run program i have empty groupbox dane. After first change value in Combobox wibierzT layout of groupbox is changing as expected (*siatka wrote in AktualA), but after next change of value in wybierzT layout hasn't change

Pawello
8th August 2012, 15:58
Here we have full code of my program:


#ifndef NOWYWPIS_H
#define NOWYWPIS_H
#include <QWidget>
#include <QGridLayout>
#include <QLabel>
#include <QComboBox>
#include <QSize>
QT_BEGIN_NAMESPACE
class QGroupBox;
class QComboBox;
class QDialogButtonBox;
class QToolButton;
QT_END_NAMESPACE
extern QMap<QString, QString> alkohol;
extern QList<QString> ListaAl; //created in wypiszal()
extern QList<QString> ListaAtr; //created in wypiszatr(QString)
extern QList<QString> ListaWart; //created in wypiszwart(QString)
extern void wypiszal();
extern void wypiszatr(QString wybranyalk);
extern void wypiszwart(QString wybranyatr);
static const QSize rozmiar(100, 100);

class parametr
{
public:
QLabel *nazwaatr;
QComboBox *Combowart;
};
class NowyWpis : public QWidget
{
Q_OBJECT
public:
NowyWpis(QWidget *parent = 0);
private slots:
void AktualIkone();
void AktualAtr();
void AktualTr();
void Dodaj();
void Anuluj();
void WybierzIkoneWpis();
void AktualLayout(QVBoxLayout *Lay);
private:
void chooseImage(const QString &title, QImage *image, QToolButton *button);
void loadImage(const QString &fileName, QImage *image, QToolButton *button);
QVBoxLayout *Layout;
QPoint imagePos(const QImage &image) const;
QGroupBox *wybortr;
QGroupBox *dane;
QComboBox *wybierztr;
QDialogButtonBox *buttonBox;
QLabel *ikonatyp;
QToolButton *ikonawpis;
QImage sourceikonawpis;
QString wybranytr;
parametr wpis;
QList<parametr> ListaDanych;
};

#endif // NOWYWPIS_H



#include <QtGui>
#include "nowywpis.h"
NowyWpis::NowyWpis(QWidget *parent)
: QWidget(parent)
{
Layout = new QVBoxLayout;
wybortr = new QGroupBox(tr("Wybor Tr"));
dane = new QGroupBox(tr("Dane"));
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok| QDialogButtonBox::Cancel);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(Dodaj()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(Anuluj()));
QGridLayout *grid = new QGridLayout;
wybierztr = new QComboBox;
wypiszal();
foreach (QString klucz, ListaAl)
{
wybierztr->addItem(klucz);
}
connect(wybierztr, SIGNAL(currentIndexChanged(int)),this, SLOT(AktualTr()));
ikonatyp = new QLabel();
connect(wybierztr, SIGNAL(currentIndexChanged(int)),this, SLOT(AktualIkone()));
connect(wybierztr, SIGNAL(currentIndexChanged(int)),this, SLOT(AktualAtr()));
grid->addWidget(wybierztr, 0, 0);
grid->addWidget(ikonatyp, 0, 1);
wybortr->setLayout(grid);
AktualLayout(Layout);
setWindowTitle(tr("Dodaj nowy wpis"));
resize(800, 600);
}
void NowyWpis::AktualLayout(QVBoxLayout *Lay)
{
//////////////////this creates Microsoft Visual C++ Library error “This application has requested the Runtime to terminate it in an unusual way.”//////////////////////////////
/* while (Lay->count()>0)
{
QWidget *widget = Lay->itemAt(0)->widget();
Lay->removeWidget(widget);
delete widget;
}
////////////////////////////////////////////////////////////////////*/ Lay->addWidget(wybortr);
Lay->addWidget(dane);
Lay->addWidget(buttonBox);
setLayout(Lay);
}
void NowyWpis::AktualTr()
{
wybranytr =(wybierztr->currentText());
}
void NowyWpis::AktualIkone()
{
ikonatyp->setAlignment(Qt::AlignBottom | Qt::AlignRight);
ikonatyp->setPixmap(QPixmap("Obrazy/Tr/"+wybranytr+".png"));
}
void NowyWpis::AktualAtr()
{
QGridLayout *siatka = new QGridLayout;
ListaDanych.clear();
while (siatka->count()>0)
{
QWidget *widget = siatka->itemAt(0)->widget();
siatka->removeWidget(widget);
delete widget;
}
wypiszatr(wybranytr);
foreach (QString atrybut, ListaAtr)
{
wpis.Combowart = new QComboBox;
wpis.nazwaatr = new QLabel;
wypiszwart(atrybut);
wpis.nazwaatr->setText(atrybut);
foreach (QString wartosc, ListaWart)
{
wpis.Combowart->addItem(wartosc);
wpis.Combowart->setEditable(true);
};
ListaDanych.append(wpis);
};
int i=0;
foreach (parametr atr, ListaDanych)
{
siatka->addWidget(atr.nazwaatr, i, 0);
siatka->addWidget(atr.Combowart, i, 1);
i++;
};
ikonawpis = new QToolButton();
ikonawpis->setIconSize(rozmiar);
connect(ikonawpis, SIGNAL(clicked()), this, SLOT(WybierzIkoneWpis()));
siatka->addWidget(ikonawpis, 0, 2, 2, 1);
dane->setLayout(siatka);
AktualLayout(Layout);
}
void NowyWpis::WybierzIkoneWpis()
{
chooseImage(tr("Wybierz ikone"), &sourceikonawpis, ikonawpis);
}
void NowyWpis::chooseImage(const QString &nazwa, QImage *obraz, QToolButton *przycisk)
{
QString plik = QFileDialog::getOpenFileName(this, nazwa);
if (!plik.isEmpty())
loadImage(plik, obraz, przycisk);
}
void NowyWpis::loadImage(const QString &plik, QImage *obraz, QToolButton *przycisk)
{
obraz->load(plik);
*obraz = obraz->scaled(rozmiar, Qt::KeepAspectRatio);
QImage obraz2(rozmiar, QImage::Format_ARGB32_Premultiplied);
QPainter painter(&obraz2);
painter.drawImage(imagePos(*obraz), *obraz);
painter.end();
przycisk->setIcon(QPixmap::fromImage(obraz2));
*obraz = obraz2;
}
QPoint NowyWpis::imagePos(const QImage &obraz) const
{
return QPoint((rozmiar.width()-obraz.width())/2,(rozmiar.height()-obraz.height())/2);
}
void NowyWpis::Dodaj()
{
}
void NowyWpis::Anuluj()
{
}


Unfortunatelly this attempt also doesnt work. After first change of value in Combobox wibierzTr layout of groupbox dane is changing as expected (*siatka wrote in AktualAlk), but after next change of value in wybierzTr layout hasn't change and I have error:
QWidget::setLayout: Attempting to set QLayout "" on QGroupBox "", which already has a layout
I don't know how to solve it

yeye_olive
8th August 2012, 16:46
QWidget::setLayout: Attempting to set QLayout "" on QGroupBox "", which already has a layout
I don't know how to solve it
The error message is self-explanatory. Hint: read the documentation of the method it mentions.

Pawello
9th August 2012, 07:56
The error message is self-explanatory. Hint: read the documentation of the method it mentions.
I understand that this problem is connected with setLayout but this knowledge doesn't help me to solve it. Please help me to do this.

yeye_olive
9th August 2012, 23:51
The documentation for QWidget::setLayout() (http://qt-project.org/doc/qt-4.8/qwidget.html#setLayout) -- have you read it? -- says that you must first delete a widget's layout before you can set another layout. You get the error message because you have not done so.

Pawello
11th August 2012, 11:18
I've already find it out but thanks for help