How do you remove the border from a QPushButton? - qt

I have some QPushButtons in the rows of a QTreeView, and they're showing up with these black borders around them that I can't seem to modify. Currently I can grey out the buttons with this code:
for (int i = 0; i < QPalette::NColorRoles; i++){
QPalette::ColorRole thisRole = static_cast<QPalette::ColorRole>(i);
QColor newColor = commitPalette.color(QPalette::Disabled,thisRole);
int grayColor = qGray(newColor.rgb());
newColor.setRgb(grayColor,grayColor,grayColor,50);
commitPalette.setColor(QPalette::Disabled, thisRole, newColor);
}
But it doesn't do anything to the border. I'd prefer to avoid using stylesheets, as I like the automatic color generation provided by QPalette's constructor

If you are using Qt creator, right click the QPushButton and setStyleSheet as border: none; Thats it.

If you set the QButton property isFlat = true it should disable the border unless it's being clicked.

I suggest using a stylesheet. From the code you can make it to a function:
void setFlatStyle(QPushButton *btn)
{
btn->setStyleSheet(QString("QPushButton {border: 0px;}"));
}
Just pass the button in there and get your result.

button.setStyleSheet("QPushButton { border: none; }")
As said #RajaRaviVarma

Related

Why does padding-left style result in QComboBox menu stretching to screen height?

Consider the following example. It creates two instances of QComboBox: one with a stylesheet, and another without. If the first one is clicked (with widget style being Fusion), the menu is sized as expected, although padding of text is inconsistent between hovered and non-hovered items. But if you click on the second one, the padding problem is now fixed, but the menu appears to have huge entries, making the menu fill the whole screen height.
#include <QComboBox>
#include <QApplication>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QComboBox box1, box2;
const QString stylesheetOrig=R"(
QComboBox::item:selected
{
background-color: #0000ff;
}
)";
box1.setStyleSheet(stylesheetOrig);
box2.setStyleSheet(stylesheetOrig+R"(
QComboBox::item
{
padding-left: 27px;
}
)");
box1.addItems({"Hello 1","Goodbye 1"});
box2.addItems({"Hello 2","Goodbye 2"});
box1.show();
box2.show();
return app.exec();
}
If I remove the padding statement, still leaving the QComboBox::item {} part, then nothing strange (and nothing useful) happens. But if I even set the padding to 1px or 0px, the stretching already happens with all its might.
Why does setting horizontal padding result in such a strange change vertically?
Wow OK, that is screwy indeed. Adding any css to a combo box makes it go into some other "retro" mode with showing icons next to the current item. I've never noticed that in many years, but I see a bunch of common threads on the issue. Seems to only affect Fusion style though, I was confused for a while on my Windows box until I figured that out.
The question is if you want the checkbox or not. Here's one way to get rid of it, the only consistent one I found after a bit of playing with it. The main trick is setting the selection colors on the ::item and not on ::item:selected (the latter makes the checkmarks appear).
QComboBox::item {
selection-background-color: #0000ff;
selection-color: palette(highlighted-text);
}
PS. Another reason for confusion and why QComboBox::item and :checked even work is that the QComboBox default item delegate (used to draw the items in the QListView which the combo box uses for the options list) "pretends" it's a QMenu: QComboMenuDelegate::paint()
So another workaround would be to use something more sane/customizable for a delegate, perhaps even a default QStyledItemDelegate.
ADDED: A version keeping the checkbox and ensuring the unchecked items have padding (w/out using padding property which appears to be FUBAR when used in a combo box item with Fusion style). The icon size seems easiest set via iconSize property -- I tried a few ways via css icon/image/element width/height but nothing affected it... probably because the iconSize property overrides it.
QComboBox { qproperty-iconSize: 12px; } /* or QComboBox::setIconSize() */
QComboBox::indicator { color: transparent; } /* to force space for the icon column */
/* Using ::item:selected vs. ::item { selection-*-color: } will apparently make the
checkbox column appear... at least with Fusion as the main style */
QComboBox::item:selected {
color: palette(highlighted-text);
background-color: #0000ff;
}
VERSION 3 (as per comments):
QComboBox { qproperty-iconSize: 12px; } /* or QComboBox::setIconSize() */
QComboBox::indicator:!checked { border: 0; } /* to force space for the icon column */
QComboBox::item { background-color: palette(base); } /* gets rid of icon|text separator */
/* Using ::item:selected vs. ::item { selection-*-color: } will apparently make the
checkbox column appear... at least with Fusion as the main style */
QComboBox::item:selected {
color: palette(highlighted-text);
background-color: #0000ff;
}
There's still a 1px frame line at the top of the unselected icon area, though it's pretty subtle. I have no idea where that comes from... tried some guesses but to no avail.

How to center a QProgressBar's chunk?

I have this audio viewer that, for lack of a better widget, uses QProgressBars to display the overall volume and the volume of each RTA bin, in addition to selecting a range of "interesting" bins:
The parent widget has a stylesheet of "background-color: DimGray;"; I don't know if that has anything to do with the problem or not. The progressbars themselves are set up like this:
AudioMeter::AudioMeter(..., QWidget* parent) :
QWidget(parent)
{
...
meter = new QProgressBar(this);
meter->setOrientation(Qt::Vertical);
meter->setFormat("");
meter->setGeometry(...);
meter->setRange(FixedPoint::Zero, FixedPoint::One);
}
and used like this:
void AudioMeter::setValue(int value)
{
meter->setValue(value);
}
The problem is that the chunks (in light blue) seem to be offset to the left by a few pixels and up by one or two, so it just doesn't look right. This is true on Lubuntu 16.04 LTS (pictured) and on Ubuntu 16.04 LTS. How can I center them?
Or if there's a better widget to use (with straightforward code, not a custom thing with 20 re-implemented methods like I've seen in some examples), I'm open to that too.
http://doc.qt.io/qt-4.8/stylesheet-examples.html#customizing-qprogressbar
http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qprogressbar
http://doc.qt.io/qt-5/stylesheet-customizing.html#the-box-model
https://www.w3schools.com/css/css_padding.asp
It looks like the right padding is probably off for some reason.
// try this and see if it helps
meter->setStyleSheet("padding: 0;");
// or just zero out the right padding
meter->setStyleSheet("padding-right: 0;");
If not, you will probably need to do some iterations of stylesheet editing...
Use a stylesheet.css file in the same path as your program:
http://doc.qt.io/qt-5/qapplication.html#QApplication
-stylesheet= stylesheet, sets the application styleSheet. The value must be a path to a file that contains the Style Sheet.
So you run your program with
meters -stylesheet=./stylesheet.css
and fill in stylesheet.css with:
QProgressBar {
/* attempt at fix by removing all padding */
padding: 0;
/* Another style to try out sometime:
QProgressBar {
border: 2px solid grey;
border-radius: 5px;
}
QProgressBar::chunk {
background-color: #05B8CC;
width: 20px;
}*/
}
I've also done prototyping of stylesheets by connecting it's reload to an application wide hotkey or a pushbutton in your program.
QString stylesheet;
QFile f("stylesheet.css");
if (f.open(QFile::ReadOnly | QFile::Text))
{
QTextStream in(&f);
stylesheet = in.readAll();
}
qApp->setStyleSheet(stylesheet);
qApp->style()->unpolish(qApp);
qApp->style()->polish(qApp);
Hope that helps.

Style QProgressBar when the value is 16

It is possible to style the QProgressBar using only QSS when the value is 16 example?
ui->progresso->setValue(16);
Using a QSS like this:
QProgressBar {
//Default QSS
...
}
QProgressBar:value(16) {
background-color: #fc0;
}
My goal is:
- When the QProgressBar is 0: It will use background-color: transparent
- When the QProgressBar is greater than 0: show a gray bar and the "chunk" will be blue
- When the QProgressBar is greater than 89: shows the "chunk" in red.
I can do this with QT + C++, but would like to know is it is possible to do this only with QSS?
Like this (this code does not exist, is just one example):
QProgressBar {
background-color: gray;
}
QProgressBar:value(0) {
background-color: transparent;
}
QProgressBar::chunk {
background-color: blue;
}
QProgressBar::chunk:minValue(90) {
background-color: red;
}
I think it is possible with help of Property Selector but only for exect values i.e.:
QProgressBar[value = 16]::chunk{
background-color: red;
}
but you can generate such stilesheet in code for each value
QString styleSheet;
for(int i = 0; i < 101; i++)
{
styleSheet.append(QString("QProgressBar[value = \"%1\"]::chunk{background-color: %2;}").arg(QString::number(i), (i < 17 ? "red" :"blue")));
}
myProgressBar->setStyleSheet(styleSheet);
I don't try it. It's just a theory based on documentation.
Update 1
Warning: If the value of the Qt property changes after the style sheet has been set, it might be necessary to force a style sheet recomputation. One way to achieve this is to unset the style sheet and set it again.
This is not possible.
The only valid extensions are in the documentation and too long to post here.
However you could handle the valueChanged( int ) signal of the QProgressBar
and set the stylesheet accordingly using setStyleSheet( ) but I figure you already know that.

QDockWidget change background color when floating

I have a QDockWidget with a transparent background, but I would like to change the background color or background image when it is floating. It doesn't look like the qt style sheets have a pseudo state to tell you whether or not they are floating, so I'd like to know: is this possible to do?
Found the solution. Add the following connection in the code:
connect(knobDock, &QDockWidget::topLevelChanged, [&] (bool isFloating)
{
if (isFloating)
{
setAttribute(Qt::WA_TranslucentBackground, false);
setAttribute(Qt::WA_NoSystemBackground, false);
}
});
This will cause the dock widgetto use whatever background is specified in the stylesheet when the dock is floating, but it will be transparent (i.e. show the mainwindow background) when it's docked.
You can use custom properties to do this.
Thanks #phyatt for link to Dynamic Properties and Stylesheets.
To declare custom property in your custom class you can write in .cpp:
setProperty("customPropertyName", 1);
or in .h (don't forget to define and implement used get/set access methods too):
Q_PROPERTY( int customPropertyName, READ getCustomPropertyName, WRITE setCustomPropertyName);
And in your global stylesheet file you can use the state of your custom property as following:
.YourClass[customPropertyName="1"] {
background-color: transparent;
}
.YourClass[customPropertyName="2"] {
background-color: black;
}
Also it's needed to reload stylesheet of the object instance after your set new property value, because stylesheets are not recalculated automatically:
object->style()->unpolish(tstFrame);
object->style()->polish(tstFrame);
object->update();
or:
object->setStyleSheet("/* */");

How to add some padding between QPushButton’s boundary and its inner text?

Longer strings don’t look too good in a QPushButton, because there’s no spacing between the text and button’s frame, i. e. the text is placed tightly within the button. Is there a way to add some padding?
You can set the padding of a QPushButton via its stylesheet.
myButton->setStyleSheet("padding: 3px;");
Or
myButton->setStyleSheet("padding-left: 5px; padding-right: 3px;"
"padding-top: 1px; padding-bottom: 1px;");
More information on stylesheets can be found here.
Rather than having to set a stylesheet for each button, I found it easier to update the sytle so that the minimum size for each button is a little bigger. You can subclass QProxyStyle which is the easiest way to modify styles, since it will apply changes to whatever style is selected ie QWindowsXPStyle, QWindowsVistaStyle, QMacStyle etc.
Override sizeFromContents like this to make the minimum size of buttons a little bigger:
class ProxyStyle : public QProxyStyle
{
public:
QSize sizeFromContents(ContentsType ct, const QStyleOption* opt, const QSize & csz, const QWidget* widget = 0) const
{
QSize sz = QProxyStyle::sizeFromContents(ct, opt, csz, widget);
if (ct == CT_PushButton)
sz.rwidth() += 20;
return sz;
}
};
And then after you create your application, but before you create your first window call:
a.setStyle(new ProxyStyle);
You can set the padding for all buttons in a window/widget with:
QPushButton { padding: 10px; }
Much better than applying to each subwidget.

Resources