QT: Checkbox font CHANGES after first click - qt

I'm having a strange problem in which a font set to a QCheckBox will change font after a first click to either check or uncheck it. I have no idea why. checkbox is a simple QCheckBox. The font change is subtle. Like from a low resolution font, to anti-aliasing with a slight color change.
I have no code that does that and I have no idea why it's happening.3
the stylesheet:
QCheckBox#TestCheck::indicator:checked
{
image: url(:/images/box_checked.png);
color: #535353;
}
QCheckBox#TestCheck::indicator:unchecked
{
image: url(:/images/box_unchecked.png);
color: #535353;
}
my code:
QFont font("Avenir LT Com");
font.setWeight(QFont::Bold);
font.setStyleStrategy(QFont::PreferAntialias);
font.setPixelSize(16);
this->checkbox = new QCheckBox(this);
this->shareScreenCheckbox->setObjectName(QString::fromUtf8("TestCheck"));
this->checkbox->setGeometry(10, 10, 400, 27);
this->checkbox->setText("This is a test");
this->checkbox->setFont(font);
this->checkbox->show();
The end result:
as you launch...
first click...
click again...
as you can see... font changes do not work. first font is different. click changes the font, and keeps it. What's going on?

I couldn't reproduce your problem, after running your code under qt 5.3. But I had a quite similar problem some time ago, with qt 5.1.1 maybe that workaround helps you too
QT 5.1.1: Checkbox in QWebview shows strange behavior under Win 7 (x64) / Win 8
class CustomStyle : public QProxyStyle
{
void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const
{
if (element == QStyle::CE_CheckBox && dynamic_cast<QWebView*>(option->styleObject))
option->styleObject->setProperty("_q_no_animation", true);
QProxyStyle::drawControl(element, option, painter, widget);
}
};
If not, you should write a bugreport at https://bugreports.qt-project.org

Related

How to customize QToolButtons from QToolBar in Qt?

I am having QToolBar with various tool buttons on it. I want to customize those buttons with some simple effects like, it should be seen that button is pressed, after pressing it should change its icon color or background color etc.
I tried but I could not succeed.
_toolbar = new QToolBar;
_toolbar->setIconSize(QSize(35,35));
_toolbar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
void createIcons()
{
_zoomInIcon = QIcon::fromTheme("zoom-in");
_zoomIn = new QAction(_zoomInIcon, "Zoom in", this);
// code for other icons
_toolbar->addAction(_zoomIn);
}
void myClass::ZoomIn()
{
_zoomIn->setCheckable(true);
//QToolButton:_zoomInIcon {background-color: red; }
//setStyleSheet('background-color: red;');
// other logic
}
Moreover I am using Qt's default icons from this default-icons
But some of the icons are not looking good specially save in and save in as.
So does any one knows more default icons apart from above link in Qt ?
Can anyone help me ?
Try something like below (not tested)
//Get the tool button using the action
QToolButton* zoomInButton = mytoolbar->widgetForAction(_zoomIn);
//Set the style you want.
zoomInButton->setStyleSheet("QToolButton:pressed"
"{"
"background-color : red;"
"}"
);
And you can use all QPushButton styles, if your tool button don't have a menu.
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbutton
The QToolButton has no menu. In this case, the QToolButton is styled
exactly like QPushButton.

QLabel change font color without changing any other style

I want to change the color of the text in a QLabel dynamically.
I have defined the color and style of the QLabel in the ui file and I want to change it when a certain event takes place.
I want to change the color without changing any other style of my QLabel.
I have found several answers adressing the issue of changing text color in a QLabel (1, 2, 3) and they all use the function setStyleSheet. This function works fine but it changes my font size and other styles related to the QLabel.
I have seen that the problem is related to setStyleSheet ignoring any previous style. The solution proposed there involves retrieving all the styles I want to maintain and setting them again together with the text color change.
This is cumbersome and difficult to maintain. If more styles were defined in the future I would need to review this part of the code to be able to reset all of them.
I would like to be able to change QLabel text color without altering any other syle. Is it possible?
If you want to manage the text color of QLabel you could wrap it with customized class.
For example:
class ColorLabel : public QLabel
{
public:
ColorLabel(const QString &text, QWidget *parent = nullptr)
: QLabel(text, parent)
{
setAutoFillBackground(true);
}
void setTextColor(const QColor &color)
{
QPalette palette = this->palette();
palette.setColor(this->backgroundRole(), color);
palette.setColor(this->foregroundRole(), color);
this->setPalette(palette);
}
};
And to use it in your code:
ColorLabel * poColorLabel = new ColorLabel("My string", this);
poColorLabel->setTextColor(Qt::red); // set label text in red color
FYI: I tested it on Fedora, Qt5.12 and it works fine.
A pragmatic approach:
Utilize the cascadingness of CSS.
Wrap your QLabel in a QWidget (don't forget a QLayout).
Set your default style on the surrounding QWidget.
Set the font color as the QLabel's only style.
You can create some style class to control a widget's style:
class WidgetStyleSheet
{
public:
// change some style's value
void setValue(const QString& styleKey, const QString& value)
{
_styleMap[styleKey] = value;
}
// to default state
void reset() {}
// form stylesheet
QString toStyleSheet() const
{
QString styleSheet;
QMapIterator<QString, QString> iter(_styleMap);
while( iter.hasNext() )
styleSheet += QString("%1: %2").arg(iter.key()).arg(iter.value());
return styleSheet;
}
private:
QMap<QString, QString> _styleMap;
}
Somewhere in your code:
WidgetStyleSheet labelSS;
// ...
labelSS.setValue("color", QString("%1").arg( QColor(255, 10, 0).name() );
labelSS.setValue("background-color", "...");
// ...
label->setStyleSheet(labelSS);
The following works fine. But it is not that elegant. This is in python. You have to pass the button name (or any other) to the following as is defined in the array
btns = ['self.hBeamBtn','self.lBeamBtn','self.allTestBtn','self.prnStatusBtn']
for btn in btns:
if str(btn_name) == str(btn):
styl = btn+'.setStyleSheet("font: bold;background-color: red;font-size: 12px;height: 28px;width: 80px;")'
eval(styl)

Hide QLineEdit blinking cursor

I am working on QT v5.2
I need to hide the blinking cursor (caret) of QLineEdit permanently.
But at the same time, I want the QLineEdit to be editable (so readOnly and/or setting editable false is not an option for me).
I am already changing the Background color of the QLineEdit when it is in focus, so I will know which QLineEdit widget is getting edited.
For my requirement, cursor (the blinking text cursor) display should not be there.
I have tried styleSheets, but I can't get the cursor hidden ( {color:transparent; text-shadow:0px 0px 0px black;} )
Can someone please let me know how can I achieve this?
There is no standard way to do that, but you can use setReadOnly method which hides the cursor. When you call this method it disables processing of keys so you'll need to force it.
Inherit from QLineEdit and reimplement keyPressEvent.
LineEdit::LineEdit(QWidget* parent)
: QLineEdit(parent)
{
setReadOnly(true);
}
void LineEdit::keyPressEvent(QKeyEvent* e)
{
setReadOnly(false);
__super::keyPressEvent(e);
setReadOnly(true);
}
As a workaround you can create a single line QTextEdit and set the width of the cursor to zero by setCursorWidth.
For a single line QTextEdit you should subclass QTextEdit and do the following:
Disable word wrap.
Disable the scroll bars (AlwaysOff).
setTabChangesFocus(true).
Set the sizePolicy to (QSizePolicy::Expanding, QSizePolicy::Fixed)
Reimplement keyPressEvent() to ignore the event when Enter/Return is hit
Reimplement sizeHint to return size depending on the font.
The implementation is :
#include <QTextEdit>
#include <QKeyEvent>
#include <QStyleOption>
#include <QApplication>
class TextEdit : public QTextEdit
{
public:
TextEdit()
{
setTabChangesFocus(true);
setWordWrapMode(QTextOption::NoWrap);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
setFixedHeight(sizeHint().height());
}
void keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
event->ignore();
else
QTextEdit::keyPressEvent(event);
}
QSize sizeHint() const
{
QFontMetrics fm(font());
int h = qMax(fm.height(), 14) + 4;
int w = fm.width(QLatin1Char('x')) * 17 + 4;
QStyleOptionFrameV2 opt;
opt.initFrom(this);
return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h).
expandedTo(QApplication::globalStrut()), this));
}
};
Now you can create an instance of TextEdit and set the cursor width to zero :
textEdit->setCursorWidth(0);
Most straight forward thing I found was stolen from this github repo:
https://github.com/igogo/qt5noblink/blob/master/qt5noblink.cpp
Basically you just want to disable the internal "blink timer" Qt thinks is somehow good UX (hint blinking cursors never were good UX and never will be - maybe try color or highlighting there eh design peeps).
So the code is pretty simple:
from PyQt5 import QtGui
app = QtGui.QApplication.instance()
app.setCursorFlashTime(0)
voilĂ .
Solution in python:
# somelibraries
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.layout = QVBoxLayout()
self.setFocus() # this is what you need!!!
container = QWidget()
container.setLayout(self.layout)
# Set the central widget of the Window.
self.setCentralWidget(container)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
I ran into the same problem but setReadOnly is not a viable option because it alters the UI behavior in other places too.
Somewhere in a Qt-forum I found the following solution that actually solves the problem exactly where it occurs without having impact on other parts.
In the first step you need to derive from QProxyStyle and overwrite the pixelMetric member function:
class CustomLineEditProxyStyle : public QProxyStyle
{
public:
virtual int pixelMetric(PixelMetric metric, const QStyleOption* option = 0, const QWidget* widget = 0) const
{
if (metric == QStyle::PM_TextCursorWidth)
return 0;
return QProxyStyle::pixelMetric(metric, option, widget);
}
};
The custom function simply handles QStyle::PM_TextCursorWidth and forwards otherwise.
In your custom LineEdit class constructor you can then use the new Style like this:
m_pCustomLineEditStyle = new CustomLineEditProxyStyle();
setStyle(m_pCustomLineEditStyle);
And don't forget to delete it in the destructor since the ownership of the style is not transferred (see documentation). You can, of course, hand the style form outside to your LineEdit instance if you wish.
Don't get complicated:
In QtDesigner ,
1.Go the the lineEdit 's property tab
2.Change focusPolicy to ClickFocus
That's it...

Qt Color Picker Widget?

I have a QDialog subclass that presents some options to the user for their selecting. One of these options is a color. I have seen the QColorDialog, and I need something much simpler, that is also a regular widget so I can add to my layout as part of my dialog. Does Qt offer anything like this or will I have to make my own? If the latter, what is the best strategy?
Have you looked at the QtColorPicker, part of Qt Solutions?
QtColorPicker provides a small widget in the form of a QComboBox with a customizable set of predefined colors for easy and fast access. Clicking the ... button will open the QColorDialog. It's licensed under LGPL so with dynamic linking and proper attribution it can be used in commercial software. Search for QtColorPicker and you'll find it. Here's a link to one site that hosts many of the Qt Solutions components:
https://github.com/pothosware/PothosFlow/tree/master/qtcolorpicker
There's a very easy way to implement that using a QPushButton to display the current color and pickup one when it is clicked:
Definition:
#include <QPushButton>
#include <QColor>
class SelectColorButton : public QPushButton
{
Q_OBJECT
public:
SelectColorButton( QWidget* parent );
void setColor( const QColor& color );
const QColor& getColor() const;
public slots:
void updateColor();
void changeColor();
private:
QColor color;
};
Implementation:
#include <QColorDialog>
SelectColorButton::SelectColorButton( QWidget* parent )
: QPushButton(parent)
{
connect( this, SIGNAL(clicked()), this, SLOT(changeColor()) );
}
void SelectColorButton::updateColor()
{
setStyleSheet( "background-color: " + color.name() );
}
void SelectColorButton::changeColor()
{
QColor newColor = QColorDialog::getColor(color, parentWidget());
if ( newColor != color )
{
setColor( newColor );
}
}
void SelectColorButton::setColor( const QColor& color )
{
this->color = color;
updateColor();
}
const QColor& SelectColorButton::getColor() const
{
return color;
}
Qt doesn't offer anything simpler than QColorDialog natively, but there are several color picking widgets as part of wwWidgets, a user made set of widgets for Qt (note that this is "wwWidgets" with a "w" and not "wxWidgets" with an "x").
I think QColorDialog is best suited for your application. If you want to go for something simpler, it will come with reduced functionality. I'm not aware of any standard widget in Qt offering such an option but you can try out the following:
QCombobox with each entry corresponding to a different color. You can maybe even have the colors of the names in their actual color.
One or more slider bars to adjust the hue, saturation, val or R,G,B components.
QLineEdit fields for individual R,G,B components. You can also have a signal / slot mechanism wherein once the user changes a color, the color shown to the user gets changed accordingly.
You can have '+' and '-' signs to increase / decrease the above color component values.
I hope the above gives you some ideas.

How to set image on QPushButton?

I want to set an image on QPushButton, and the size of QPushButton should depend on the size of the image. I am able to do this when using QLabel, but not with QPushButton.
So, if anyone has a solution, then please help me out.
What you can do is use a pixmap as an icon and then put this icon onto the button.
To make sure the size of the button will be correct, you have to reisze the icon according to the pixmap size.
Something like this should work :
QPixmap pixmap("image_path");
QIcon ButtonIcon(pixmap);
button->setIcon(ButtonIcon);
button->setIconSize(pixmap.rect().size());
QPushButton *button = new QPushButton;
button->setIcon(QIcon(":/icons/..."));
button->setIconSize(QSize(65, 65));
You can also use:
button.setStyleSheet("qproperty-icon: url(:/path/to/images.png);");
Note: This is a little hacky. You should use this only as last resort. Icons should be set from C++ code or Qt Designer.
You may also want to set the button size.
QPixmap pixmap("image_path");
QIcon ButtonIcon(pixmap);
button->setIcon(ButtonIcon);
button->setIconSize(pixmap.rect().size());
button->setFixedSize(pixmap.rect().size());
I don't think you can set arbitrarily sized images on any of the existing button classes.
If you want a simple image behaving like a button, you can write your own QAbstractButton-subclass, something like:
class ImageButton : public QAbstractButton {
Q_OBJECT
public:
...
void setPixmap( const QPixmap& pm ) { m_pixmap = pm; update(); }
QSize sizeHint() const { return m_pixmap.size(); }
protected:
void paintEvent( QPaintEvent* e ) {
QPainter p( this );
p.drawPixmap( 0, 0, m_pixmap );
}
};
You can do this in QtDesigner. Just click on your button then go to icon property and then choose your image file.
This is old but it is still useful,
Fully tested with QT5.3.
Be carreful, example concerning the ressources path :
In my case I created a ressources directory named "Ressources" in the source directory project.
The folder "ressources" contain pictures and icons.Then I added a prefix "Images" in Qt So the pixmap path become:
QPixmap pixmap(":/images/Ressources/icone_pdf.png");
JF
Just use this code
QPixmap pixmap("path_to_icon");
QIcon iconBack(pixmap);
Note that:"path_to_icon" is the path of image icon in file .qrc of your project You can find how to add .qrc file here
In case anybody needs a PyQt version of the first answer:
class PictureButton(QAbstractButton):
def __init__(self, picture, parent):
super().__init__(parent)
self.setPicture(QPixmap(picture))
def setPicture(self, picture):
self.picture = picture
self.update()
def sizeHint(self):
return self.picture.size()
def paintEvent(self, e):
painter = QPainter(self)
painter.drawPixmap(0, 0, self.picture)

Resources