QPushButton resize after changing color - c++

I want to modify the background-color of QPushButtons. The problem is that modifying the background color using setStyleSheet("QPushButton { background-color: #00FF00 }"); , the button size also scales.
before
after
I understand that by changing the background-color, the entire button style sheet gets overwritten and reset to some default (How to override just one property:value pair in Qt StyleSheet).
My question is: how can I set the size of the button such that it is the same size as the original?
I am using MacOSX and I tried all combinations of height, minimum-height, padding.

If it's just about setting the background color, then using the QPalette would be an option.
QPushButton button;
QPalette palette = button.palette();
palette.setColor(QPalette::Background, QColor("#00FF00");
button.setPalette(palette);

I thinks it's because min-width and min-height are not specified.
According to the documentation:
If this property is not specified, the minimum width is derived based
on the widget's contents and the style.
One possibility could be to get the size of the button before setting the style, and set that size when you apply the background color.
I.e. (in this example, we have a UI file with a pushbutton called pushButton):
QString width ("min-width: " +
QString::number(ui.pushButton->size().width()) +
" px; " +
"max-width: " +
QString::number(ui.pushButton->size().width()) +
" px;");
QString height ("min-height: " +
QString::number(ui.pushButton->size().height()) +
" px; " +
"max-height: " +
QString::number(ui.pushButton->size().height()) +
" px;");
QString style ("#pushButton { " + width + height +
"background-color: black; }");
qApp->setStyleSheet(style);
I'm setting both min and max width and height because the reference says
If you want a widget with a fixed width, set the min-width and
max-width to the same value.
Of course, an easier solution could be to resize the pushbutton after setting the background color. Something like this:
int width = ui.pushButton->size().width();
int height = ui.pushButton->size().height();
QString style ("#pushButton { background-color: black; }");
qApp->setStyleSheet(style);
ui.pushButton->resize(width, height);

Related

Set color of tabified QDockWidget tabs

I am creating a QDockWidget, and I want it's tabs(when tabified) or title bar(when not tabified) to flash between two colors.
I am currently doing the following, but only the body flashes between two colors:
//Setup the array of styles for the flash:
std::array<const char*, 2> flashStyles = {
" background-color: lightblue; color: black;",
" background-color: orange; color: black; "
};
//Setup the timer and kick it off:
connect(m_flashTimer, &QTimer::timeout, [=]()
{
//Perform the flash by alternating the background:
setStyleSheet(flashStyles[
m_pass == 0 ? m_pass++ : m_pass--
]);
update();
});
I can't seem to find any properties that would allow me to change the tab color / title bar color. Do I need to set the tab color properties somewhere else?
You need to find out which Widget is used internally by QDockWidget to display tabs. Then use the appropriate styles with the correct selector. Probably you need to select a QTabBar which is a descendant of QDockWidget. This could look like:
QDockWidget QTabBar {}
Maybe these links can also help you:
http://doc.qt.io/archives/qt-4.8/stylesheet-syntax.html
http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qdockwidget
http://doc.qt.io/archives/qt-4.8/stylesheet-reference.html

Qt - QLabel won't resize with fixed ratio

Introduction
I am working with the Designer inside the Qt Creator and have a QMainWindow with a QLabel in it. Because the program loads pictures and displays them inside the label i want that the label resizes with a ratio of 1.25 inside setted boundaries when expanding or shrinking the QMainWindow. The label should resize INDEPENDENT, again INDEPENDENT from its content.
What i want:
Open the main window for first time:
width: 640, height: 512
Shrinking the main window:
label shrinks with constant ratio (640/512) till minimum size (320 x 256)
Expanding the main window:
label expands with constant ratio (640/512) till maximum size (1280 x 1024)
1. Approach:
Therefor i...
added a QLabel(called imageLabel) inside the centralWidget of the QMainWindow
set the centralWidget's layout to grid layout (QGridLayout)
sed the following properties to the QLabel:
geometry - Can not set the values because of grid layout usages!
minimumSize > width: 320, height: 256 (Minimum values)
maximumSize > width: 1280, height: 1024 (Maximum values)
sizePolicy > Horizontal Policy == Vertical Policy == Expanding
Element structure:
This doesn't work because i can not set an initial size in the 'geometry' section. The label does not scale with fixed ratio although it respects minimum and maximum values.
2. Approach:
Following that answer i set an initial pixmap:
QPixmap p;
ui->imageLabel->setPixmap(p.scaled(640, 512, Qt::KeepAspectRatio));
Which didn't change anything.
3. Approach:
I also applied the other answer's class and promoted it to the widget:
That didn't change anything too.
4. Approach:
I then combined the 2. and 3. approach and set an initial pixmap which...
...didn't change anything.
Here is what it does for the approaches 1. - 4.:
5. Approach
Adding the label of 4. approach into a widget:
Well the label doesn't resize at all:
So, how can get the label to have an initial size of 640 x 512 and scale with fixed ratio between 1280 x 1024 and 320 x 256 ?
A possible solution is to install an eventFilter to the centralwidget so doing the required calculation is set the size.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->centralWidget->installEventFilter(this);
ui->imageLabel->setPixmap(QPixmap(":/image.png"));
ui->imageLabel->setScaledContents(true);
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
const float ratio = 1.25;
if(watched == ui->centralWidget && event->type() == QEvent::Resize
&& ui->centralWidget->width() > 0
&& ui->centralWidget->height() > 0){
float central_ratio = 1.0*ui->centralWidget->width()/ui->centralWidget->height(); QSize s;
if(central_ratio > ratio){
s = QSize(ratio*ui->centralWidget->height(), ui->centralWidget->height());
}
else{
s = QSize(ui->centralWidget->width(), ui->centralWidget->width()/ratio);
}
ui->imageLabel->resize(s);
}
return QMainWindow::eventFilter(watched, event);
}

QListWidget - Removing Padding & Consistent Column Width

I created a QListWidget using setViewMode(QListView::ListMode) and setFlow(QListView::TopToBottom) to get this:
The large space between the icon and the text looks odd so I tried to remove it with:
list->setStyleSheet("QListView::icon { padding-right: 0px; }");
and also:
list->setStyleSheet("QListView::icon { padding: 0px; }");
but neither removes the space. Is there any way to remove the space between the icon and the text?
Also, you'll see from the above screenshot that QListWidget uses variable column widths, but I wanted all the columns to have the same width. I tried this solution:
int width = 0;
int numItems = list->count();
QFontMetrics metrics(list->font());
for (int i = 0 ; i < numItems ; ++i)
{
if (metrics.boundingRect(list->item(i)->text()).width() > width)
width = metrics.boundingRect(list->item(i)->text()).width();
}
list->setGridSize(QSize(width+30, 16));
However, it doesn't seem to work consistently and I had to use +30 to account for the icon area, which isn't a very good solution, particularly if the size of the icon changes.
Is there a better way to get all the columns the same width?

Align to the right text from QLabel and QLineEdit

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.

QScrollBar + QScrollAera in QTabWidget

My question is simple : how can I set a QScrollBar in my QScrollArea. I have tested a lot of things but nothing work ... Maybe it's a problem to set a QScrollArea in a QTabWidget ? Here is the code :
void GamesWindow::createTabSucces()
{
std::string nameImg;
_succesPage = new QWidget(_tab);
_tab->addTab(_succesPage, " Succes ");
scrollArea = new QScrollArea(_succesPage);
scrollArea->setBackgroundRole(QPalette::Dark);
scrollArea->setFixedSize(500,500);
/* Integration of QScrollBar */
for (int i = 0; i < 45; i++)
{
nameImg = "img/allAchiv/";
nameImg += intToString(i + 1);
nameImg += ".jpg";
_imgSucc[i] = new QLabel(scrollArea);
_imgSucc[i]->setPixmap(QPixmap(QString(nameImg.c_str())));
_imgSucc[i]->setGeometry((14 + (85 * (i % 5))), 46 + ((i / 5) * 85), 60, 60);
}
}
In fact, I add pictures in a tab where is created a QScrollArea (like 8-9 lines of pictures) but only 5 are visible, the others are hide, because they are at the bottom, out of the defined zone.
Any idea ? Thank's.
You must:
add a layout to your page (QVBoxLayout)
add the scroll area to that page layout
add a layout to the viewport() widget in the scroll area (QVBoxLayout)
add your QLabels to that viewport layout
This way you won't need to call setGeometry on each label
You need to set a widget to your scroll area and add your pictures to the widget's layout. Check QScrollArea::setWidget(QWidget *widget)
I'm almost sure that you can't add scroll to a tab widget but my idea is just to try make more tabs that can be shown and see if the slider comes up by default.