Qt setGeometry to negative value doesn't work - c++

Im working with QT and I have a form with a QLabel in a QFrame. I want to set the QLabel's geometry so the bottom part of the QLabel is in the same place of the bottom of the frame. Since the label is longer than the frame, it's y coordinate should be negative.
int pos = ui->imageFrame->height() - ui->imageLabel->pixmap()->height();
ui->imageLabel->setGeometry(0, pos, ui->imageFrame->width(), p.height());
Although when printing the QLabel's geometry, the y coordinate is correct, the label is showing on the upper part of the frame.
Help is much appreciated.

You can set the label's alignment with setAlignment. Here's a working example:
#include <QtWidgets>
#include "MyWidget.h"
MyWidget::MyWidget()
{
setFixedSize(200,200);
QLabel *label = new QLabel;
label->setPixmap(QPixmap("/some/image/file.jpg"));
label->setAlignment(Qt::AlignBottom);
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addWidget(label);
hbox->setContentsMargins(0,0,0,0);
setLayout(hbox);
}

Related

How can I stretch a QLayout or QFrame, nested within a bigger layout?

I currently have this code set up to create a sidebar and I'm not entirely sure how to stretch it so that the left, top, and bottom sides touch the edge of the window.
QFrame *sidebar = new QFrame;
QLabel *sideItemA = new QLabel("Item A");
QLabel *sideItemB = new QLabel("Item B");
QVBoxLayout *sidebarLayout = new QVBoxLayout;
sidebarLayout->addWidget(sideItemA);
sidebarLayout->addWidget(sideItemB);
sidebarLayout->addStretch();
sidebar->setLayout(sidebarLayout);
sidebar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
sidebar->setStyleSheet("background-color:#FFFFFF");
sidebar->setMinimumWidth(150);
mainLayout->addWidget(sidebar);
Here is a screenshot of what the above code looks like:
I've tried doing this using nested layouts too and I get the same result. Any pointers? Is this even the best way to do it?

QtChart - C++ - Saving a chart which wasn't displayed

I'm trying to save a chart to a file, in a QTextDocument in this example :
QTextDocument doc("Frame rate test\n");
QTextCursor cursor(&doc);
cursor.movePosition(QTextCursor::End);
if (getTestFinishedStatus())
{
QPixmap pix = _pFrameRateChart->grab(); //_pFrameRateChart is QChartView
cursor.insertImage(pix.toImage());
}
QTextDocumentWriter docWriter;
docWriter.setFileName("framerate.odf");
docWriter.setFormat("ODF");
docWriter.write(&doc);
The problem is the result isn't same if I'm displaying the chart in an ui.
Here is the result when not displayed :
Here is the result when displayed :
Obviously I would like to have the second result even when I don't add the ChartView to a widget to display it on an ui.
I've tried resizing the QChartView, resizing the QChart, adding the Chart to a temporarly widget and QVBoxLayout then saving it, showing temporarly the QChartView before saving it etc... but didn't managed to get a good result.
I use the following code to render a QGraphivsView on a Pixmap, since QtCharts is based on QGraphivsView, I think this will also work.
Try to render the image instead of trying to grab the pixmap.
void Printer::putProfileImage(QRect profilePlaceholder, QRect viewPort, QPainter *painter, QGraphivsView* profile)
{
int x = profilePlaceholder.x() - viewPort.x();
int y = profilePlaceholder.y() - viewPort.y();
QRect pos(x, y, profilePlaceholder.width(), profilePlaceholder.height());
profile->render(painter, pos);
}
I didn't find any easy way to this, so here's my solution, which is more like a workaround though :
QPixmap ChartView::getChartPixmap()
{
QWidget* w = new QWidget; //creating a temporary widget, which will enable to display the chart
w->resize(REPORT_IMAGE_WIDTH, REPORT_IMAGE_HEIGHT);
QVBoxLayout *vl;
vl = new QVBoxLayout(w);
vl->addWidget(this); //'this' being the QChartView
w->show(); //showing the widget so it is resized and can be grabbed with the correct dimensions
QTest::qWait(500); //we need to wait for a little for the graph to be drawn otherwise you'll still have the same size problem
QPixmap pixmap = w->grab(); //retrieve the pixmap
w->hide(); //hiding the widget
return pixmap;
}
It's working but you'll have a small window opened with the graph for 500 ms.

QGraphicsScene::clear doesn't change sceneRect

I have a QGraphicsScene "scene" and QGraphicsView "graphicsView".
I have a drawing method. When I need redraw all the graphics, I call this method. Everything is OK. But I realized that scene->clear() doesn't change the sceneRect.
Also I tried:
graphicsView->items().clear();
scene->clear();
graphicsView->viewport()->update();
After that, if I get the sceneRect by
QRectF bound = scene->sceneRect();
qDebug() << bound.width();
qDebug() << bound.height();
I expect the bound.width and bound.height to be '0'. But they aren't. I see the previous values everytime. How to clear sceneRect when I clear the scene itself?
It gives some problems that sceneRect remains the same, while using graphicsView->fitInView() method.I use following code:
QRectF bounds = scene->sceneRect();
bounds.setWidth(bounds.width()*1.007); // to give some margins
bounds.setHeight(bounds.height()); // same as above
graphicsView->fitInView(bounds);
Although I completely cleared the scene and added only one rather small rectangle, the rectangle didn't fit into view because of sceneRect remains too big.
I hope I could explain my problem.
From the Qt Docs (emphasis mine):
This property holds the scene rectangle; the bounding rectangle of the scene
The scene rectangle defines the extent of the scene. It is primarily used by QGraphicsView to determine the view's default scrollable area, and by QGraphicsScene to manage item indexing.
If unset, or if set to a null QRectF, sceneRect() will return the largest bounding rect of all items on the scene since the scene was created (i.e., a rectangle that grows when items are added to or moved in the scene, but never shrinks).
Therefore, the only way to shrink the sceneRect is to use setSceneRect.
The better question is why do you need to set scene rectangle? In case you have a smaller scene don't set it. Instead add items to the scene and fit in view based on items bounding rectangle as in my example below:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsRectItem>
#include <QPointF>
#include <QDebug>
#include <qglobal.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
_scene = new QGraphicsScene(this);
ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->graphicsView->setScene(_scene);
connect(ui->button, SIGNAL(released()), this, SLOT(_handleRelease()));
}
MainWindow::~MainWindow()
{
delete ui;
}
int MainWindow::_random(int min, int max)
{
return qrand() % ((max + 1) - min) + min;
}
void MainWindow::_handleRelease()
{
_scene->clear();
QGraphicsRectItem* pRect1 = _scene->addRect(0, 0, _random(50,100), _random(50,100));
QGraphicsRectItem* pRect2 = _scene->addRect(0, 0, _random(20,50), _random(20,50));
pRect1->setPos(QPoint(40,40));
pRect2->setPos(QPoint(20,20));
ui->graphicsView->fitInView(_scene->itemsBoundingRect(),Qt::KeepAspectRatio);
}
In case you have a large scene with hundreds of items this approach will be slow because:
If the scene rect is unset, QGraphicsScene will use the bounding area
of all items, as returned by itemsBoundingRect(), as the scene rect.
However, itemsBoundingRect() is a relatively time consuming function,
as it operates by collecting positional information for every item on
the scene. Because of this, you should always set the scene rect when
operating on large scenes.

QLineEdit visible width Setting?

How may I set the visible width of QLineEdit with Qt 4.8.1 and up. Example would be to set the visible width to some pixel size or character width. I wish to only use C++ not QML.
My thought is in the direction of this block:
QHBoxLayout *nameRow = new QHBoxLayout;
QLineEdit *firstNameText = new QLineEdit,
*middleIntText = new QLineEdit,
*lastNameText = new QLineEdit;
//Whatever method is needed here to edit visible width
//firstNameText->???
//middleIntText->???
//lastNameText->???
nameRow->addWidget(firstNameText);
nameRow->addWidget(middleIntText);
nameRow->addWidget(lastNameText);
layout->addLayout(nameRow);
QWidget window;
window.setLayout(layout);
window.show();
Answer Update: (or see below)
firstNameText->setMaximumWidth(100);
firstNameText->setFixedWidth(120);
middleIntText->setMaximumWidth(50);
middleIntText->setFixedWidth(60);
lastNameText->setMaximumWidth(100);
lastNameText->setFixedWidth(120);
firstNameText->setMaximumWidth(100);
firstNameText->setFixedWidth(120);
You can use thse two functions and they will adjust the width accordingly.

Qt QHBoxLayout issue?

I use an extended QGroupBox as the widget for QDockWidget in my QMainWindow.
Here is the code snippet:
RzPlaneViewerControlPanelWidget::RzPlaneViewerControlPanelWidget(QWidget *parent) : QGroupBox(parent) {
// TODO Auto-generated constructor stub
init();
}
void RzPlaneViewerControlPanelWidget::init()
{
QHBoxLayout *hbox=new QHBoxLayout;
hbox->setSizeConstraint(hbox->SetMinimumSize);
hbox->setSpacing(0);
hbox->setStretch(1,0);
setMaximumHeight(50);
QScrollBar *scrollbar=new QScrollBar;
scrollbar->setOrientation(Qt::Horizontal);
scrollbar->setMouseTracking(true);
scrollbar->setFocusPolicy(Qt::StrongFocus);
scrollbar->setMinimum(0);
scrollbar->setSingleStep(1);
QLineEdit *qlineedit = new QLineEdit;
qlineedit->setMaximumWidth(60);
qlineedit->setReadOnly(true);
hbox->addWidget(scrollbar);
hbox->addWidget(qlineedit);
//hbox->addWidget(new )
setLayout(hbox);
}
Here is how I add this widget to QDockWidget :
RzPlaneViewerControlPanelWidget *controlPanel=new RzPlaneViewerControlPanelWidget ;
controlPanel->init();
QDockWidget controlPanelDockWidet=new QDockWidget;
controlPanelDockWidet->setAllowedAreas(Qt::BottomDockWidgetArea);
controlPanelDockWidet->setFeatures(QDockWidget::DockWidgetVerticalTitleBar);
controlPanelDockWidet->setWidget(controlPanel);
But the ScrollBar is not stretched as I expected -
Here's how it looks like -
This is what I want -
From a quick read, I'd try doing:
hbox->addWidget(scrollbar, 1);
The second (optional) argument to addWidget is the stretch factor. From the Qt docs:
If the stretch factor is 0 and nothing else in the QBoxLayout has a stretch factor greater than zero, the space is distributed according to the QWidget:sizePolicy() of each widget that's involved.
Also, note that your:
hbox->setStretch(1,0);
call does not have any effect, as it is setting the qlineedit's stretch factor to 0, but that's already the default.