Align to the right text from QLabel and QLineEdit - c++

I have a QLabel just below a QLineEdit with the same size and alignment properties:
QLineEdit *lineEdit = new QLineEdit("999");
lineEdit->setFixedWidth(100);
lineEdit->setAlignment(Qt::AlignRight);
//
QLabel *label = new QLabel("999");
label->setFixedWidth(100);
label->setAlignment(Qt::AlignRight);
//
QLayout *layout = new QVBoxLayout;
layout->addWidget(lineEdit);
layout->addWidget(label);
Here is how this is rendered:
How can I have the text of the bottom label exactly right-aligned to the text of the lineEdit?
Full award if you find a solution that works on all platforms, and that also works when the font sizes are different in the lineEdit and label.

Unfortunately it may not be possible, at least not out of the box, the right margin will not work, as it is always 0 even when the text is obviously offset to the left. The reason for this is this offset is not determined by the margins, but depends on the combination of platform GUI style and particular font's metrics that's being used, and its value is "conveniently" not available in the class public interface, there is no way to get to it.
You can get the font metrics easily, but you can't get the QStyleOptionFrame as the method required is protected, accessing it will require to subclass QLineEdit. However, if you are lucky, that value is very likely to be zero, so you could go with something as simple as this:
QVBoxLayout *layout = new QVBoxLayout;
QLineEdit *lineEdit = new QLineEdit("999");
lineEdit->setAlignment(Qt::AlignRight);
QLabel *label = new QLabel("999");
label->setAlignment(Qt::AlignRight);
int offsetValue = lineEdit->fontMetrics().averageCharWidth();
label->setIndent(offsetValue);
setLayout(layout);
layout->addWidget(lineEdit);
layout->addWidget(label);
If that doesn't work correctly for you, you will have no other choice but to subclass QLineEdit, carefully examine its paint event, determine where the offset is being calculated, and store that value in a public member so it can be accessed from the outside to be used to offset the label.
I personally got lucky with that code:

Would you be able to instead of using a QLineEdit and a QLabel to use two QLineEdits?
Consider the following:
QWidget* widget = new QWidget();
// Original line edit
QLineEdit *lineEdit1 = new QLineEdit("999");
lineEdit1->setFixedWidth(100);
lineEdit1->setAlignment(Qt::AlignRight);
lineEdit1->setStyleSheet("border-width: 2px;");
// A suggestion if you want a label
QLabel *label = new QLabel("999");
label->setFixedWidth(100);
label->setAlignment(Qt::AlignRight);
label->setStyleSheet("border: 2px solid rgba(255, 0, 0, 0%)");
// Alternatively if you can use another QLineEdit
QLineEdit *lineEdit2 = new QLineEdit("999");
lineEdit2->setFixedWidth(100);
lineEdit2->setAlignment(Qt::AlignRight);
lineEdit2->setReadOnly(true);
lineEdit2->setStyleSheet("background: rgba(0, 0, 0, 0%); "
"border-width: 2px; "
"border-style: solid; "
"border-color: rgba(0, 0, 0, 0%);");
// Bring it all together
QLayout *layout = new QVBoxLayout(widget);
layout->addWidget(lineEdit1);
layout->addWidget(label);
layout->addWidget(lineEdit2);
widget->show();
It forces all borders to be 2px, so on different platforms it should be the same. The second QLineEdit should not look different than the QLabel (The text color looks slightly darker than that of the label though, which might be a good thing since it matches the original edit)
The added benefit of using a QLineEdit instead of the QLabel is that the value is now selectable...
Disclaimer: I have only tested on Linux and I have not done a pixel level comparison.
Edit: I see the alignment fails with different font sizes.

simply, you can use the indent property of the QLabel.
https://doc.qt.io/qt-5/qlabel.html#indent-prop
The indent property can take +/- values. maybe the margin feature can do its job.

Related

QTableWidget real screen size

I work with A QTableWidget in my app. To calculate the max. Columns to show I need to get the real width of the QTableWidget. I tried different ways:
this (QTableWidget)
this->geometry()->width() = Will always report 640.
this->horizontalHeader()->length() = Will always report 1660 here in case of the amount of columns.
But the QTableWidget has a size of exact 1000 pixel. This confuse me.
My first Idea wa, ok you ask the app at the wrong position about the size.
SO I also asked after the MDIChild was build.
QVBoxLayout * dlgSplitter = new QVBoxLayout(this);
QHBoxLayout * topNav = new QHBoxLayout(this);
QWidget * wdgSplitter = new QWidget(this);
QLabel *labelTopNav = new QLabel(this);
labelTopNav->setText(tr("This is a header"));
topNav->addWidget(labelTopNav);
topNav->setContentsMargins(1,8,1,0);
dlgSplitter->setContentsMargins(0,0,0,0);
dlgSplitter->setSpacing(0);
dlgSplitter->setMargin(0);
dlgSplitter->addLayout(topNav);
scanBoard = new QScanBoard(200, 83); //This ist he "this->" control from above
//scrollArea->setWidget(scanBoard);
dlgSplitter->addWidget(scanBoard);
wdgSplitter->setLayout(dlgSplitter);
this->setCentralWidget(wdgSplitter);
int nWidth = scanBoard->geometry().width();
qDebug("Breite: %d ",nWidth);
But this also throws the same data as the class itself do.
Do anybody know a way to read the size of the QTableWidget without its contents, just its frame?

How do I display a border around a QWebEngineView?

I have a QGraphicsWidget which I am using to paint and display a number of items including a QWebEngineView using the QGraphicsProxyWidget. I am able to load web content into QWebEngineView, but I would like to make the view contain a border. I have used "setStyleSheet" to try to add a border, but this does not appear to work. The following code is in the constructor of my QGraphicsWidget class to add the QWebEngineView:
QWebEngineView * view = new QWebEngineView();
view->setFixedWidth(700);
view->setFixedHeight(200);
view->setStyleSheet("border: 10px border-color: black");
view->load(QUrl("qrc:/myresources/guidetext.html"));
QGraphicsProxyWidget * proxyView = new QGraphicsProxyWidget(this);
proxyView->setWidget(view);
This is how it currently looks:
How I would like it to look like:
Problem
Normally, setting the Qt::WA_StyledBackground attribute, then the correct stylesheet and the content margins like that:
view->setAttribute(Qt::WA_StyledBackground);
view->setStyleSheet("border: 1px solid black;");
view->setContentsMargins(1, 1, 1, 1);
should do the trick.
However, it seems that QWebEngineView does not respect the content margins:
Workaround
I would suggest you to make QWebEngineView child of another QWidget and style the parent widget instead.
Example
Here is an example I have prepared for you of how to change your code in order to implement the proposed solution:
auto *proxyView = new QGraphicsProxyWidget();
auto *widget = new QWidget();
auto *view = new QWebEngineView(widget);
auto *l = new QVBoxLayout(widget);
l->addWidget(view);
l->setContentsMargins(1, 1, 1, 1);
widget->setAttribute(Qt::WA_StyledBackground);
widget->setStyleSheet("border: 1px solid black;");
widget->setFixedWidth(700);
widget->setFixedHeight(200);
view->load(QUrl("qrc:/myresources/guidetext.html"));
proxyView->setWidget(widget);
Result
Here is the result when loading Google:

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?

QT GridLayout add Stacked QLabel

I am creating an image gallery, i've implemented the reading in of Files and showing them in a resizable scroll-Area. We've decided to add meta-tags / Buttons and i am searching for a convenient way not to change too much but add this little features.
Any suggestion how i can achieve this? Can i add two Qlabels to each other? I tried to stuck two labels in a new layout and push this to the scrollWidgetLayout, but then i have only one Thumbnail.
//Create new ThumbNail-Object
thumbNail = new Thumbnail(ui->scrollArea);
scrollWidgetLayout->addWidget(thumbNail);
In the picture you can see what i have already and what i need (yellow).
You create a widget that acts like a container and put the labels inside it. Set a layout to this widget, I used QVBoxLayout. A better design would be to create a custom widget by subclassing QWidget, but I just used QFrame to make the example quick and simple.
centralWidget()->setLayout(new QVBoxLayout);
QScrollArea *area = new QScrollArea(this);
area->setWidgetResizable(true);
area->setWidget(new QWidget);
QGridLayout *grid = new QGridLayout;
area->widget()->setLayout(grid);
centralWidget()->layout()->addWidget(area);
for(int row = 0; row < 2; row++)
{
for(int column = 0; column < 5; column++)
{
QFrame *container = new QFrame; // this is your widget.. you can also subclass QWidget to make a custom widget.. might be better design
container->setStyleSheet("QFrame{border: 1px solid black;}"); // just to see the shapes better.. you don't need this
container->setLayout(new QVBoxLayout); // a layout for your widget.. again, if you subclass QWidget do this in its constructor
container->layout()->addWidget(new QLabel("TOP")); // the top label.. in your case where you show the icon
container->layout()->addWidget(new QLabel("BOTTOM")); // the bottom label.. in your case where you show the tag
grid->addWidget(container, row, column); // add the widget to the grid
}
}

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.