[SOLVED] QWidget subclass drawing in wrong place
-
The widget is inside a QGridLayout as the line 21 shows. This layout is inside a tabwidget and resizes normally. I did the same procedure to all tabs using QWidgets as QPushButtons, QLineedits, etc and it works fine.
Just when I put my widget inside it does not work. Theres something I am no figuring out about this code.
-
when I do that, the QPushButton resizes but not my widget (fluxocaixawidget)
@
//Tool Box 3
QGridLayout *gridLayoutInvestimento5 = new QGridLayout(boxInvestimento3);fluxoCaixaWidget *fluxoCaixa = new fluxoCaixaWidget(boxInvestimento3); QPushButton *button = new QPushButton("Teste", boxInvestimento3); QVBoxLayout *vertical = new QVBoxLayout(boxInvestimento3); vertical->addWidget(button); vertical->addWidget(fluxoCaixa); //gridLayoutInvestimento5->addWidget(fluxoCaixa); gridLayoutInvestimento5->addLayout(vertical,0,0); boxInvestimento3->setLayout(gridLayoutInvestimento5); //------------------------------------------------------------------------
@
-
When giving a layout a widget parent you set it on the widget. This means that currently you start by setting gridLayoutInvestimento5 as layout of boxInvestimento3. Then you create fluxoCaixa and button as child of boxInvestimento3. Then you create vertical as child of boxInvestimento3 thus making it its layout manager (you should have a warning telling you that boxInvestimento3 already has a layout manager when running).
Then you put both button and fluxoCaixa in vertical and then you put that in gridLayoutInvestimento5 and finally set gridLayoutInvestimento5 as boxInvestimento3.That's pretty messy
@
//Tool Box 3
fluxoCaixaWidget *fluxoCaixa = new fluxoCaixaWidget;
QPushButton *button = new QPushButton(tr("Teste"));
QVBoxLayout *vertical = new QVBoxLayout;
vertical->addWidget(button);
vertical->addWidget(fluxoCaixa);QGridLayout *gridLayoutInvestimento5 = new QGridLayout(boxInvestimento3); gridLayoutInvestimento5->addLayout(vertical,0,0);
@
When using layouts the parenting is done for you.
-
Hello SGaist!
First of all, thanks for the help.
I changed the code, but it stills no expanding or shrinking when the window is rezised.
The button resizes but fluxocaixawidget dont.
@
//Tool Box 3
QGridLayout *gridLayoutInvestimento5 = new QGridLayout(boxInvestimento3);fluxoCaixaWidget *fluxoCaixa = new fluxoCaixaWidget(boxInvestimento3); QPushButton *button = new QPushButton("Teste", boxInvestimento3); gridLayoutInvestimento5->addWidget(button,0,0); gridLayoutInvestimento5->addWidget(fluxoCaixa,1,0);
@
-
Did you tried it within just a simple widget ?
-
I did 2 examples with my custom widget (fluxocaixawidget). In both cases my widget do not change the size when the window is resized.
First
@
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);fluxoCaixaWidget *fluxo = new fluxoCaixaWidget(this); setCentralWidget(fluxo);
}
MainWindow::~MainWindow()
{
delete ui;
}
@Second
@
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);fluxoCaixaWidget *fluxo = new fluxoCaixaWidget(this); QPushButton *button = new QPushButton("Teste", this); QGridLayout *gridLayout = new QGridLayout(this->ui->frame); gridLayout->addWidget(button,0,0); gridLayout->addWidget(fluxo,1,0);
}
MainWindow::~MainWindow()
{
delete ui;
}
@fluxocaixawidget.cpp
@
#include "fluxocaixawidget.h"#include <QDebug>
#include <QGridLayout>fluxoCaixaWidget::fluxoCaixaWidget(QWidget *parent) :
QWidget(parent)
{
this->setMouseTracking(true);
//this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);linhaTempo.setRect(20,this->sizeHint().height() / 2 - 15, this->sizeHint().width()-40, 30); dentro = false; fluxo = NULL;
}
void fluxoCaixaWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);QPen caneta; QBrush pincel(Qt::white); painter.setBrush(pincel); painter.drawRect(0,0,this->sizeHint().width(), this->sizeHint().height()); if(this->dentro == true) { painter.drawText(QRect(20, 15, linhaTempo.width(), 25), "Linha do tempo", QTextOption::QTextOption(Qt::AlignCenter)); caneta.setWidth(3); } else { caneta.setWidth(2); } painter.setPen(caneta); painter.drawRect(linhaTempo); if(fluxo != NULL) { for(int i = 0; i < fluxo->count(); i++) { if(fluxo->at(i) < 0) { caneta.setColor(Qt::red); } else { if(fluxo->at(i) == 0) { caneta.setColor(Qt::black); } else { if(fluxo->at(i) > 0) { caneta.setColor(Qt::blue); } } } if(fluxoDentro.at(i) == true) { QString valor = QString::number(fluxo->at(i)); painter.drawText(QRect(20, 15, linhaTempo.width(), 25), valor, QTextOption::QTextOption(Qt::AlignCenter)); caneta.setWidth(3); } else { caneta.setWidth(2); } painter.setPen(caneta); painter.drawRect(fluxoRect.at(i)); } } //this->updateGeometry();
}
void fluxoCaixaWidget::mouseMoveEvent(QMouseEvent *)
{
if(linhaTempo.contains(this->mapFromGlobal(QCursor::pos())))
{
dentro = true;
}
else
{
dentro = false;
}for(int i = 0; i < fluxoRect.count(); i++) { if(fluxoRect.at(i).contains(this->mapFromGlobal(QCursor::pos()))) { fluxoDentro.insert(i, true); dentro = false; } else { fluxoDentro.insert(i, false); } } this->update();
}
void fluxoCaixaWidget::setFluxo(QList<double> *f)
{
fluxo = f;fluxoRect.clear(); fluxoDentro.clear(); int espacamento = 0; if(fluxo->count() > 1) { espacamento = linhaTempo.width() / (fluxo->count() - 1); } for(int i = 0; i < fluxo->count(); i++) { if(i == 0) { fluxoRect.append(QRect(20, linhaTempo.y(), 10, 50)); fluxoDentro.append(false); } else { fluxoRect.append(QRect(20 + espacamento * i, linhaTempo.y(), 10, 50)); fluxoDentro.append(false); } } this->update();
}
QSize fluxoCaixaWidget::sizeHint() const
{
return QSize(350, 200);
}
@fluxocaixawidget.h
@
#ifndef FLUXOCAIXAWIDGET_H
#define FLUXOCAIXAWIDGET_H#include <QWidget>
#include <QPainter>class fluxoCaixaWidget : public QWidget
{
Q_OBJECT
public:
explicit fluxoCaixaWidget(QWidget *parent = 0);void setFluxo(QList<double> *f); QSize sizeHint() const;
protected:
void paintEvent(QPaintEvent *);
void mouseMoveEvent(QMouseEvent *);private:
bool dentro;
QRect linhaTempo;
QList<double> *fluxo;
QList<QRect> fluxoRect;
QList<bool> fluxoDentro;signals:
public slots:
};
#endif // FLUXOCAIXAWIDGET_H
@ -
You initialize linhaTempo once and never update it. One way would be to reimplement the resizeEvent method to update linhaTempo. But not the question is: do you really need that variable ? Can't you just use the widget geometry in paintEvent ?
-
Well, yes, I need it. This variable is a timeline, a very important point in the widget.
This is my first custem widget. Could you show me how to use the geometry the make it resizable?
-
Have a look at e.g. the analog clock example in Qt's documentation
-
SOLVED
SGaist, thank you for your replies and time
@
#include "fluxocaixawidget.h"#include <QDebug>
#include <QGridLayout>fluxoCaixaWidget::fluxoCaixaWidget(QWidget *parent) :
QWidget(parent)
{
this->setMouseTracking(true);container.setRect(0,0,350,200); dentro = false; fluxo = NULL;
}
void fluxoCaixaWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);QPen caneta; QBrush pincel(Qt::white); painter.setBrush(pincel); linhaTempo.setRect(20,container.height()/2 - 15, container.width()-40, 30); painter.drawRect(container); if(this->dentro == true) { painter.drawText(QRect(20, 15, linhaTempo.width(), 25), "Linha do tempo", QTextOption::QTextOption(Qt::AlignCenter)); caneta.setWidth(3); } else { caneta.setWidth(2); } painter.setPen(caneta); painter.drawRect(linhaTempo); if(fluxo != NULL) { for(int i = 0; i < fluxo->count(); i++) { if(fluxo->at(i) < 0) { caneta.setColor(Qt::red); } else { if(fluxo->at(i) == 0) { caneta.setColor(Qt::black); } else { if(fluxo->at(i) > 0) { caneta.setColor(Qt::blue); } } } if(fluxoDentro.at(i) == true) { QString valor = QString::number(fluxo->at(i)); painter.drawText(QRect(20, 15, linhaTempo.width(), 25), valor, QTextOption::QTextOption(Qt::AlignCenter)); caneta.setWidth(3); } else { caneta.setWidth(2); } painter.setPen(caneta); int espacamento = 0; if(fluxo->count() > 1) { espacamento = linhaTempo.width() / (fluxo->count() - 1); } if(i == 0) { painter.drawRect(20, linhaTempo.y(), 4, 50); } else { painter.drawRect(20 + espacamento * i, linhaTempo.y(), 4, 50); } } }
}
void fluxoCaixaWidget::mouseMoveEvent(QMouseEvent *)
{
if(linhaTempo.contains(this->mapFromGlobal(QCursor::pos())))
{
dentro = true;
}
else
{
dentro = false;
}for(int i = 0; i < fluxoRect.count(); i++) { if(fluxoRect.at(i).contains(this->mapFromGlobal(QCursor::pos()))) { fluxoDentro.insert(i, true); dentro = false; } else { fluxoDentro.insert(i, false); } } this->update();
}
void fluxoCaixaWidget::resizeEvent(QResizeEvent *)
{
container.setRect(0,0, width(), height());if(fluxo != NULL) { this->setFluxo(fluxo); }
}
void fluxoCaixaWidget::setFluxo(QList<double> *f)
{
fluxo = f;fluxoRect.clear(); fluxoDentro.clear(); int espacamento = 0; if(fluxo->count() > 1) { espacamento = linhaTempo.width() / (fluxo->count() - 1); } for(int i = 0; i < fluxo->count(); i++) { if(i == 0) { fluxoRect.append(QRect(20, linhaTempo.y(), 4, 50)); fluxoDentro.append(false); } else { fluxoRect.append(QRect(20 + espacamento * i, linhaTempo.y(), 4, 50)); fluxoDentro.append(false); } }
}
@