Customise button in QT - c++

I need to create a toggle button in qt and it should look like the below image. It should show the ON image when it is turned on and remain at this state until it is toggled again. It should show the OFF image in the off case. Please help me on this.

You can use images as an icon (sadly, it won't scale with button by default), create a class which would paint those images in the handler for paint event, or you can use those images in QSS stylesheet. QSS is CSS 2.0 analog for Qt's GUI elements.
Note that after using stylesheet all changes to visuals of said element should be done through changes to stylesheet as well.
THose styles can be set through form editor by right-clicking a widget and choosing "Change stylesheet" or through code directly by calling setStyleSheet, depending which workflow you prefer.
button->setStyleSheet(
"QPushButton { border-image: url(:/Resources/chbUnchecked.png); }"
"QPushButton::checked { border-image: url(:/Resources/chbChecked.png); }" );
border-image Scales image to border limits, replacing standard border.There is also a background-image which fills widget's surface with regular repeats.
To limit this change only for checkable buttons:
button->setStyleSheet(
"QPushButton[checkable="true"] { border-image: url(:/Resources/chbUnchecked.png); }"
"QPushButton::checked[checkable="true"] { border-image: url(:/Resources/chbChecked.png); }" );
:/Resources/ is a path within app's resources.
QSS syntax: https://doc.qt.io/Qt-5/stylesheet-syntax.html
Note that QSS have selectors, so it's it have same "Cascading" ability as CSS. You can assign styles bulk based on hierarchical location on GUI, class-inheritances, class names, quasi-states and names.
If you set style above to a window, all instances of QPushButton within that window would have said style. If you define a new class for such Button, you can use its name instead of standard button class, although QSS for base class would apply to it.

the easiest way is to add the on-off images to your project as resources
then set the button as checkable and in its properties set the images to be rendered when is selected or not..(under icon -> selected on and selected off)
of course you have create images with a properly geometry... in the screenshot they look pretty small because I borrow them from your post..
:)

Related

QT layout output with 4K display

I have always worked with QT in c++ to create UI with a standard monitor resolution of 1920×1440 pixels.
Now I have changed to a new PC UHD 4K and I am experiencing some troubles with the result.
Here an example: I create with Qt a simple UI:
Then if I create the Preview from QT Creator/Designer, I get exactly the result I want:
Instead when I compile and execute the program, the result of the UI is much different:
Do you know how I can solve this issue?
From the Qt Designer screenshot it looks like your toplevel widget in that dialog does not have a layout.
To add a layout to the toplevel widget, select it in the widget tree on the right side and then click on one of the layouts, e.g. a QVBoxLayout.
What happened here was that the initial widget sizes were correct for the current resolution, but resize events never got promoted from the dialog class to the next widget level. This has nothing to do with high DPIs; it's plain old layout management. You were just lucky that the sizes were okay'ish initially.
Please notice that you might also add some margins to the outermost layout because it will shrink-wrap the contents tightly, so the dialog will look very odd at first. Open the dialog layout's properties to see the margins and play with them.
You can set the font size in your push button to look like this:
"QPushButton{"
"padding: 4px;"
"color: #000000;"
"background-color: red;"
"border: 2px;"
**"font-size:12px;"**
"}";

Qt pushbutton palette

I'm using GUI form editor in qt creator, I have set the background
(right_click -> change_stylesheet->Add Resource -> background_image)
Then I added a few buttons, the buttons are colored like the background, instead of being normal - default. I was trying this with properties->palette but with poor results. I'm new to qt, so I am asking for your help.
Like in CSS, Qt Style Sheet will apply your styling rules to any item that matches them.
If you just write:
background-image: url(:/my_background.png);
it will change the background of all the widgets in your application.
If you want to change the background of the main window only, you should write:
QMainWindow {
background-image: url(:/my_background.png);
}
That will apply the background image only to the QMainWindow object.
For an detailed explanation of Qt Style Sheet, I invite you to read the official documentation here.

Setting and manipulating Icons in QT

I want to add icons in QMainWindow and when i will click that window it should perform some action like popup some window. So what should i use for the icon menu?
You could use the QToolButton class to accomplish this task.
It is possible to set it to only contain an image/icon without text.
l buttons are normally created when new QAction instances are created with QToolBar::addAction() or existing actions are added to a toolbar with QToolBar::addAction(). It is also possible to construct tool buttons in the same way as any other widget, and arrange them alongside other widgets in layouts.
A tool button's icon is set as QIcon. This makes it possible to specify different pixmaps for the disabled and active state. The disabled pixmap is used when the button's functionality is not available. The active pixmap is displayed when the button is auto-raised because the mouse pointer is hovering over it.
The button's look and dimension is adjustable with setToolButtonStyle() and setIconSize(). When used inside a QToolBar in a QMainWindow, the button automatically adjusts to QMainWindow's settings (see QMainWindow::setToolButtonStyle() and QMainWindow::setIconSize()). Instead of an icon, a tool button can also display an arrow symbol, specified with arrowType.
So, you would use these methods:
QAction * QToolBar::addAction(const QIcon & icon, const QString & text)
Creates a new action with the given icon and text. This action is added to the end of the toolbar.
and
toolButtonStyle : Qt::ToolButtonStyle
This property holds whether the tool button displays an icon only, text only, or text beside/below the icon.
The default is Qt::ToolButtonIconOnly.
To have the style of toolbuttons follow the system settings (as available in GNOME and KDE desktop environments), set this property to Qt::ToolButtonFollowStyle.
QToolButton automatically connects this slot to the relevant signal in the QMainWindow in which is resides.
As you can see, the default is icon only.

Positioning QPushButtons via qss in QT

I have a set of five buttons that I am trying to position in a qss file. The default position that I have set up in the ui file works for one of the layouts I need. However, I want to group the buttons differently in the other theme.
I am new to qss files and have been experimenting, but cannot figure out if some things are possible. The "left" property is defined here: http://doc.qt.io/archives/4.6/stylesheet.html#left-attr but nothing happens when I try to use it.
margin-left actually moves the button, but only relationally. So, if the buttons are positioned in the ui file with a gap of 100 between them, a margin-left for the second button in the list is offset by 100.
What am I doing wrong? Could it be some setting in the ui file that is preventing it from moving? I already "broke layout" and it doesn't seem to matter. Is there a good resource you'd suggest?
Here is a sample of my qss file. The left has no effect.
QPushButton#Button_1
{
min-width: 50;
max-width: 50;
min-height: 50;
max-height: 50;
position:absolute;
subcontrol-origin: border;
left:200;
}
EDIT:
I've figured out that I can change the position of the button by deriving a class from QPushButton and making a "GeomX" qproperty. This seems to work, but I am running into an odd issue now. When I first load my app, it draws the buttons as they are positioned on the ui file. When I use the "change theme" option that I've coded, and select the currently loaded theme, it moves the buttons as I'd expect. However, resizing the app dumps them back to the ui positions and restarting also places them back in their ui positions. Is there a setting in the ui file that I could alter to get it to stop moving them? Is there a load-order issue that I need to address? Is it possible to even address this? What is going on?
Generally speaking, style sheets in Qt are used to alter the way a widget is drawn, not where it is positioned (except to add padding/margin). As the documentation you've referenced mentions, the "left" property is specific to sub-controls (that is, components within a widget and not the widget itself).
What it sounds like you're trying to accomplish (change the layout depending on the theme) would likely require a different approach. A couple of options would be to react to when the theme changes by:
Moving around your spacers in your layout to move the buttons to the desired position
Using a stacked widget, one page in the stack for each layout you desire, and change which page in the stack you're showing depending on what theme you're using.

How to prevent an icon being highlighted?

I have a listwidget with items which have icons. When the item is selected both the text and the icon are highlighted. My problem is that when the icon is highlighted it just goes entirely black because I'm using only two colours. Is there a way to prevent the icon from being selected?
You can add additional images to the QIcon, depending on it's state:
QIcon icon(...);
icon.addFile("selected.png", size, QIcon::Selected);
See also the documentation of QIcon::addFile().
Best solution was to make your own qstyle which handled the painting of the backgrounds of listitem sub controls and draw the icons qrect as white
Another possibility would be to reimplement QListWidgetItem... You could therefore have a bigger control on how things gets done during the process of selection and painting...
Of course, it's a lot more work...