Get updated size of QGraphicsView - c++

In my Qt Application I am dynamically creating QGraphicsView(s) and adding them inside
a QGridLayout.
When I add first view inside grid, the view covers all the available space inside grid.
Then I add second view and there are now two equally sized views inside grid.
Then I add third view and there are now three equally sized views inside grid.
And so on.
How can I get updated size of first view?
Below is my trial but I think this is not working.
//Definition of viewsPerRow
static const int viewsPerRow = 3;
void window::newViewRequested()
{
QGraphicsView *view = new QGraphicsView;
view->setVisible(true);
viewVector.push_back(view);
for(int i = viewGrid->count(); i < viewVector.count(); i++)
{
viewGrid->addWidget(view,i / viewsPerRow ,i % viewsPerRow);
}
qDebug()<<viewGrid->cellRect(0,0);
}

You probably should use the QWidget::rect() methods to get the geometry of the views themselves. Here is a sample that should work as intended.
QVector< QGraphicsView* > views;
for (int i=0 ; i < 3; ++i) {
QGraphicsView *view = new QGraphicsView;
view->setVisible(true);
viewGrid->addWidget(view, i ,0);
views.push_back(view);
}
qDebug() << "The view size of the first view is " << views[0]->rect();

Not sure why you need the size of the first view, but Qt does only few redraws at the time it "thinks" it is suited. Therefore you can't rely on a size you query outside the view.
I'd try to use the resizeEvent to get notified when the size of an item changes and perform the necessary actions then.

Related

How to change the background color from the header(horizontal / vertical) QTableWidget on Qt?

I would like to know how to change the background color from the headers (horizontal / vertical) from the object QTableWidget on Qt.
I already Know how to change all the headers together, using :
ui->tableWidget->setStyleSheet("QHeaderView::section {background-color:red}");
But I need change individually the items. Obviously if this is possible .
There are at least 2 ways to solve this problem. Very easy one:
Just use setHeaderData() and set specific colors for specific sections.
QTableView *tview = new QTableView;
QStandardItemModel *md = new QStandardItemModel(4, 4);
for (int row = 0; row < 4; ++row) {
for (int column = 0; column < 4; ++column) {
QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column));
md->setItem(row, column, item);
}
}
tview->setModel(md);
tview->model()->setHeaderData(0,Qt::Horizontal,QBrush(QColor("red")),Qt::BackgroundRole);
tview->show();
But u nfortunately it will not work on some systems... Qt uses the platform style. For example, my Windows doesn't allow to change header's color. So this code doesn't work on my machine. Fortunately, it can be solved easily with changing global style. So next code works:
//... same code ...
tview->show();
QApplication::setStyle(QStyleFactory::create("Fusion"));
If you don't want to change style, then you should create your own HeaderView. Probably, something similar as here.

Lock app orientation to landscape in Qt

I would like to lock my app developed with Qt to landscape orientation, even if the screen display is portrait. I have tried adding to my code the resizeEvent method found here: http://qt-project.org/doc/qt-4.8/widgets-orientation.html, but my app still does not display correctly. Here is my code for resizeEvent:
void MainWindow::resizeEvent(QResizeEvent *event)
{
QSize size = event->size();
qDebug() << size;
bool isLandscape = size.width() > size.height();
if (isLandscape == false){
size.transpose();
}
this->setFixedSize(size);
}
Does anyone know how to do this in Qt 4.8.5? I am trying to display an app for a 320x240 display.
Thanks
You can't really follow that example. It shows two different widgets depending on the orientation. Furthermore the doc warns about modifying size properties inside resizeEvent.
One solution would be to set a fix aspect ratio similar to 320x240 by overloading QWidget::heightForWidth. You wouldn't need to overload resizeEvent.
It will look like
int MainWindow::heightForWidth( int w ) {
return (w * 240 )/320;
}
heightForWidth is discussed in detail in https://stackoverflow.com/a/1160476/1122645.
edit:
sizeHint is used by the layout of the parent to compute the size of children widgets. In general, it make sense to implement it as
QSize MainWindow::sizeHint() const
{
int w = //some width you seem fit
return QSize( w, heightForWidth(w) );
}
but if MainWindow is top level then it will not change anything. You can also alter heightForWidth flag of your current size policy
QSizePolicy currPolicy = this->sizePolicy();
currPolicy->setHeightForWidth(true);
this->SetSizePolicy(currPolicy);
But again, if it is a top level widget I doesnt change much.
Anyway you don't need to call updateGeometry.

Wrong background color in custom QWidget

In my GUI, I have a scrollable area and a widget to be displayed in it defined like so:
_scoreBoxScroll = new QScrollArea(this);
_scoreBoxScroll->setFrameShape(QFrame::NoFrame);
_scoreBoxWidget = new QWidget(this);
_scoreBoxWidgetLayout = new QHBoxLayout(_scoreBoxWidget);
Some custom widgets are added later in a function:
for (int i = 1; i <= _db->gamesPerRound(); ++i) {
GameWidget *newGame = new GameWidget(_scoreBoxWidget, i, _db->playersString(MT::singular), _db->boogerScore());
_scoreBoxWidgetLayout->addWidget(newGame);
}
_scoreBoxScroll->setWidget(_scoreBoxWidget);
This results in a wrong background color for the GameWidgets:
When I add those widgets in the constructor with the very same code (and the _db calls replaced with static values, as when the constructor is called, there's no _db yet), the widgets are displayed with the correct color:
In case this is interesting: the whole code can be found in git://l3u.de/muckturnier.git, the posted code resides in ScorePage/ScorePage.cpp.
Why is a different color displayed here? And how can I fix this? Thanks in advance for all help!
Edit: the code in the constructor used in the second example is (as I don't have _db there):
_scoreBoxWidget = new QWidget(this);
_scoreBoxWidgetLayout = new QHBoxLayout(_scoreBoxWidget);
_scoreBoxLayout->addWidget(_scoreBoxWidget);
for (int i = 1; i <= 2; ++i) {
GameWidget *newGame = new GameWidget(this, i, QString::fromUtf8("Paar"), 21);
_scoreBoxWidgetLayout->addWidget(newGame);
}
_scoreBoxScroll->setWidget(_scoreBoxWidget);
Edit: I have created a minimalistic demo in the "demo" branch on git://l3u.de:muckturnier.git – I would be very glad if anyone could explain this behaviour!
Okay, I can answer my question myself now. It's due to the fact that QScrollArea::setWidget() calls setAutoFillBackground(true) on the added widget. When I add a manual
_scoreBoxWidget->setAutoFillBackground(false);
after the
_scoreBoxScroll->setWidget(_scoreBoxWidget);
the background color is as expected.

Spacing between widgets in QHBoxLayout

I'm trying to create a GUI with QtCreator. For this GUI, I need to display several images with different sizes next to each other. These images should be touching each other.
I use a QWidget with a QHBoxLayout, where I add the labels (with different sizes) containing the images.
According to related questions, I should use setSpacing and setContentsMargin to remove these spaces, but that won't work; I tried several times.
Here's the code:
QWidget *widget = new QWidget(ui->tagcloud);
QHBoxLayout * l = new QHBoxLayout(widget);
ui->tagcloud->setWidget(widget);
for(int i=0;i<list.size();++i)
{
QLabel *lab = new QLabel;
QPixmap pic((list[i].imgPath).c_str()); //This fetches the image
int sizeChange = 50 + (2*list[i].percent); //Calculates the size of the image
lab->setFixedSize(QSize(sizeChange, sizeChange));
lab->setPixmap(pic);
lab->setScaledContents(true);
l->addWidget(lab);
l->setSpacing(0);
}
However, when I run this, the spacing remains the same (i.e. definitely not zero).
If I add more labels to the layout, the spacing seems to get smaller.
Can anyone explain or help me? Thanks!
Setting spacing to 0 and adding stretch before and after works for me :
l->addStretch();
for(int i = 0; i < list.size(); ++i)
{
QLabel *lab = new QLabel;
QPixmap pic((list[i].imgPath).c_str()); //This fetches the image
int sizeChange = 50 + (2*list[i].percent); //Calculates the size of the image
lab->setFixedSize(QSize(sizeChange, sizeChange));
lab->setPixmap(pic);
lab->setScaledContents(true);
l->addWidget(lab);
}
l->addStretch();
l->setSpacing(0);
Also this works I think
l->setSizeConstraint(QLayout::SetMaximumSize);

QScrollArea with multiple QWidgets only shows empty box

I am trying to create a widget that would display some information. Each information would be a QWidget that contains multiple QLabel with text (the information). My idea is to put multiple (array of these) into a QScrollArea so that the user can view them scrolling up and down. The following code:
InfoWidget::InfoWidget(QWidget* parent) : QWidget(parent){
widgets = new QVector<MarkerInfoWidget*>();
csv_data = 0;
csv_velocity = 0;
labels = 0;
infoWidgetLayout = new QVBoxLayout(this);
setLayout(infoWidgetLayout);
scrollArea = new QScrollArea(this);
scrollWidgetLayout = new QVBoxLayout(scrollArea);
scrollArea->setLayout(scrollWidgetLayout);
infoWidgetLayout->addWidget(scrollArea);
//Test
QString name = "TEST";
for(int i=0; i<10; i++){
MarkerInfoWidget* markerWidget = new MarkerInfoWidget(name, scrollArea);
scrollWidgetLayout->addWidget(markerWidget);
widgets->append(markerWidget);
}
}
Both MarkerInfoWidget and InfoWidget extends QWidget. What I am getting is simply a box that has very small text:
If I drag it out and re-size it, it display correctly:
What I have noticed is that if I re-size it too small, it does not generate scrolls. What do I need to fix this?
I guess changing:
scrollArea->setLayout(scrollWidgetLayout);
to sth like:
QFrame* frame = new QFrame(scrollArea);
frame->setLayout(scrollWidgetLayout);
scrollArea->setWidget(frame);
As far as i know you have to put widget into QScrollableArea to make it really scrollable. Setting its layout is probably not the thing you want to do.