QHBoxLayout addwidget() order and two qglwidget share texture object - qt

I created two QGLwidget objects:
slicerCanvas* slicerX_;
secCan* secWid_;
secWid_ = new secCan(this);
//slicerX_ load data and create texture object share with secWid_
slicerX_ = new slicerCanvas(this,secWid_);
and in the main window, I use QHBoxLayout:
hBox_ = new QHBoxLayout;
hBox_->addWidget(slicerX_);
hBox_->addWidget(secWid_);
centerWidget_->setLayout(hBox_);
It works right, but if I addWidget like this:
hBox_ = new QHBoxLayout;
hBox_->addWidget(secWid_);//first
hBox_->addWidget(slicerX_);//second
centerWidget_->setLayout(hBox_);
The secWid_ will not paint anything, only slicerX_ paints correctly. I am confused as to why.

Related

Qwt shows old axes and titles on a new plot

I am trying to use Qwt in my project. I need to draw a plot which can be replaced by another based on some conditions.
My widget is created with the following code:
QStackedWidget *stackedWidget = new QStackedWidget(ui->m_capacitancesWidget);
for(int i = 0; i < sensors; ++i) {
QwtPlot *plot = new QwtPlot();
m_capacitancesPlots.push_back(plot); // convenience vector for easy access to plots
plot->setTitle(tr("Mutual capacitances"));
plot->setCanvasBackground(Qt::white);
plot->insertLegend(new QwtLegend());
QwtPlotCurve *curve = new QwtPlotCurve();
curve->setTitle(tr("Sensor %1").arg(1));
curve->setPen(Qt::green, 1);
curve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
curve->attach(plot);
// actually I add another two curves which have some data, but I omit it in this snippet
stackedWidget->addWidget(plot);
}
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(stackedWidget);
ui->m_capacitancesWidget->setLayout(layout);
Here is my widget:
Sometimes I am loading new data and want to refresh the widget. Since there could be different number of sensors and so on, I call the following code to clean things up and then the same code above to create the view from scratch:
for(int i = 0; i < m_capacitancesPlots.size(); ++i)
m_capacitancesPlots[i]->detachItems(QwtPlotItem::Rtti_PlotItem, true);
m_capacitancesPlots.clear();
if(ui->m_capacitancesWidget->layout())
delete ui->m_capacitancesWidget->layout();
But after this, my widget looks like this:
Axes are doubled, titles are doubled. Plots seem to be ok, but when I draw the third one (green in legend), it's not visible. It seems that although QStackedWidget and QwtPlot are completely new, I see some cached old QwtPlot. How to properly clean my widget and draw new QwtPlot?

Why do the next two code sequences behave differently?

I don't understand why the first code sequence creates a QWidget where the elements overlap, while the second one behaves correctly.
The only difference is that in the first one there is a QVBoxLayout pointer, while in the second one it's an object.
It's about passing by reference vs passing by pointer? I really don't get the subtle difference.
First one:
QVBoxLayout vbox;
vbox.setSpacing(2);
QPushButton* quitButton = new QPushButton("Qsdfsuit");
QFont fnt = quitButton->font();
fnt.setPointSize(18);
fnt.setBold(true);
fnt.setFamily("Arial");
quitButton->setFont(fnt);
connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
QLCDNumber* lcd = new QLCDNumber(2);
QSlider* slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 99);
slider->setValue(0);
connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
vbox.addWidget(quitButton);
vbox.addWidget(lcd);
vbox.addWidget(slider);
this->setLayout(&vbox);
The second one:
QVBoxLayout* vbox = new QVBoxLayout();
vbox->setSpacing(2);
QPushButton* quitButton = new QPushButton("Qsdfsuit");
QFont fnt = quitButton->font();
fnt.setPointSize(18);
fnt.setBold(true);
fnt.setFamily("Arial");
quitButton->setFont(fnt);
connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
QLCDNumber* lcd = new QLCDNumber(2);
QSlider* slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 99);
slider->setValue(0);
connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
vbox->addWidget(quitButton);
vbox->addWidget(lcd);
vbox->addWidget(slider);
this->setLayout(vbox);
In the first segment QVBoxLayout vbox; is created on the stack.
It is destroyed as soon as the method execution if finished.
In the second segment QVBoxLayout* box is created in a heap and it's not destroyed until the widget is alive.
Layouts in Qt do their job when a widget is shown or resized that's why they should exist until a widget exists.
More information:
The stack and the heap
Blocks and local variables

QGraphicsProxyWidget::setPos(qreal x, qreal y) doesn't place correctly in a QGraphicsScene when coordinates > 2^15

I have a QGraphicsScene of big dimension for displaying a database content.
Part of the database is made of pictures that I place in the QGraphicsScene thanks to the method setPos() of a QGraphicsPixmapItem and this works fine with thousands of pictures.
In front of these pictures, I place QCheckboxes that are finally accessible through QGraphicsProxyWidgets. But QGraphicsProxyWidget::setPos(qreal x, qreal y) results in casting provided coordinates in signed short in the QGraphicsScene.
However, doing a QGraphicsProxyWidget::pos() returns correctly the original coordinates, even above 2^16.
Here is the code:
QCheckBox* checkbox = new QCheckBox("", this);
QWidget* dummyWidget = new QWidget; //used for having a transparent background
dummyWidget->setStyleSheet("background-color:transparent;"
"outline-color:transparent;"
"font-size: 8pt;");
QHBoxLayout* dummyLayout = new QHBoxLayout(dummyWidget);
dummyLayout->addWidget(checkbox);
QGraphicsProxyWidget* proxyWidget = scene.addWidget(dummyWidget);
proxyWidget->setPos(0, 120*i);
When 120*i is between 32769 and 65536, QChekBoxes don't show. For above values, QCheckBoxes are shown like if y = value - 65536.
I have tried many things without success, like
- proxyWidget->moveBy
- dummyWidget->move
- dummyWidget->setFixedSize(0, 240*i); checkbox->move(0, 120*i);
Any solution?
PS: The toolchain/cross-toolchain I depend from embeds QT4.8.1. for the desktop side.
I have no way to change that so upgrading to QT5.x is not an option.
You can use next trick:
void setNewPos(QGraphicsItem *item, QPointF pos)
{
item->resetTransform();
QTransform trans = item->transform();
item->setTransform(trans.translate(pos.x(), pos.y()));
}
Now, you can call this func:
QPushButton *btn = new QPushButton("Hello, people!");
QGraphicsProxyWidget *wdgItem = scene->addWidget(btn);
setNewPos(wdgItem, view->mapToScene(0,0)); // There's scenePos can have any coords

point or arrow on variables/methods in Qt

can you please tell me the difference between the "point" and the "arrow", for example :
file.open
and
->start() (with QThread)
i thought the arrow was used for "methods", whereas the "point" is used for "attributes", but open for example is a method.
thanks for your answer
It's not just for Qt, the . is used when the variable in question is referencing the actual instance of the type/class.
Example:
QLabel label(QString("Hello"));
label.show();
The -> is used when the variable is a pointer that can hold the address of the type/class.
Example:
QLabel *label = new QLabel(QString("Hello"));
label->show();
-> is used for pointers. if x is declared as pointer to sth, x-> is used for attributes, otherwise . is used.
QLabel *label = new QLabel(tr("Heyy"));
QHBoxLayout hbox = new QHBoxLayout;
label->show();
hbox.addWidget("foo");

Qt Qbrush issue

What is the difference in the following code,
QGraphicsScene * scence = new QGraphicsScene();
QBrush *brush = new QBrush((QColor(60,20,20)));
scence->setBackgroundBrush(*brush);
QGraphicsView *view = new QGraphicsView();
view->setScene(scence);
//view->setBackgroundBrush(*brush);
//view->setCacheMode(QGraphicsView::CacheBackground);
view->showFullScreen();
gives black color background
QGraphicsScene * scence = new QGraphicsScene();
QBrush *brush = new QBrush();
brush->setColor(QColor(60,20,20));
scence->setBackgroundBrush(*brush);
QGraphicsView *view = new QGraphicsView();
view->setScene(scence);
//view->setBackgroundBrush(*brush);
//view->setCacheMode(QGraphicsView::CacheBackground);
view->showFullScreen();
it gives nothing.
As the Qt doc says :
QBrush::QBrush ()
Constructs a default black brush with the style Qt::NoBrush (i.e. this brush will not fill shapes).
In your second example, you have to set the style of the QBrush object by setStyle(), for example with Qt::SolidPattern.
QGraphicsScene * scence = new QGraphicsScene();
QBrush *brush = new QBrush();
brush->setStyle(Qt::SolidPattern); // Fix your problem !
brush->setColor(QColor(60,20,20));
scence->setBackgroundBrush(*brush);
QGraphicsView *view = new QGraphicsView();
view->setScene(scence);
//view->setBackgroundBrush(*brush);
//view->setCacheMode(QGraphicsView::CacheBackground);
view->showFullScreen();
Hope it helps !
An alternate approach that achieves the same result is to put the color in the brush constructor, and that applies a default style of solid:
QBrush *brush = new QBrush (QColor (60, 20, 20));
The constructors that take a color have an optional parameter for the style, which defaults to Qt::SolidPattern. Both approaches produce the same result, but this one uses two fewer lines of code.

Resources