Positioning QPushButtons via qss in QT - c++

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.

Related

Customise button in QT

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..
:)

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;"**
"}";

Creating a scrollable window without Layouts

I am trying to achieve something what, I thought, would be a super easy thing to do. But for some reason QtDesigner is driving me crazy, it simply won't work...
I created a GUI and freely arranged different elements in the window, without layout or anything like that. At some point there were to many elements, so all I wanted to to, was to make it scrollable up and down, to see all elements.
So I added a ScrollArea in QtDesigner and added all elements as children of this ScrollArea (which btw also was a pain in the ass, because apparently drag and drop in the Object viewer is not a thing, and editing the .ui file by hand, is also not allowed... great).
So the result I have now is the following:
before resize - no scrollbar, elements at bottom inaccessible
resized vertically - some stuff still snapped off at the bottom
So as you see, although I created a ScrollArea... There is no scroll area. So I googled a little bit and found out that you can add layouts to your scrollarea, and yey, finally, a scroll bar! But how in this world am I supposed to arrange the elements in the way you see in the screenshots, with layouts. They are so super restrictive.
How am I supposed to simply get a vertical scrollbar, without this restrictive layout stuff?!
Here is how my object viewer looks
And here is what is called upon GUI creation:
ui->setupUi(this);
//setCentralWidget(ui->scrollArea);
//ui->scrollArea->setWidgetResizable(true);
I tried it with, and without the commented lines. No scrollbar, no matter what I do.
Try this to fix it:
In Qt Designer:
Select QScrollArea object.
Uncheck the QScrollArea properties widgetResizable.
In C++:
// If you want to set `widgetResizable` programmaticly
ui->scrollArea->setWidgetResizable(false); // Optional if you did it in Qt Designer
ui->scrollArea->widget()->adjustSize();

Qt - Unable to move scrollbars in QScrollArea

I have an application that includes a vertical layout of push buttons, which is inside a container widget, which is inside a scroll area, which is part of another layout, which is applied to the main window. The setup is currently in a working state, and I'm able to scroll using the vertical scrollbar on the right side of the window.
The problem is that this application is meant for a touchscreen, and the default scrollbar is too small for fingers. I've been able to resize it using setFixedWidth() and/or stylesheets; however, the left edge of the scrollbar remains in the same position. The result is that the scrollbar only expands to the right, putting it off-screen.
I've tried figuring out how to move the scrollbar back to the left so that the entirety of it can be seen on-screen, but I've not been able to find out how to do this yet, as I'm still fairly new to Qt. I've tried using setGeometry(), but it seems to have no effect whatsoever. I even tried creating a separate QScrollBar and adding it manually, but I get the same off-screen result.
Is there something in the layout settings that could be causing this?
You should use stylesheets to resize scrollbars:
ui->scrollArea->setStyleSheet(QString("\
QScrollBar:horizontal { height: 30px; } \
QScrollBar:vertical { width: 30px; }"));

Scrolling in C++ Builder RadioGroup

I have RadioGroup with many buttons. Now when I add an item, they become smaller and smaller. How is it possible to make them scrollable?
TRadioGroup does not natively support scrolling. However, what you can do instead is the following:
place a TGroupBox on your UI.
place a TScrollBox onto the TGroupBox, set its Align property to alClient, and its BorderStyle property to bsNone.
place a TRadioGroup onto the TScrollBox, clear its Caption property, and set its Left property to -2 and its Top property to -15 (or whatever the TRadioGroup.Font is set to plus a few extra pixels). This positioning is needed because you cannot turn off the TRadioGroup's borders or the space reserved for its Caption.
Tweak the TScrollBox.HorzScrollBar.Range and TScrollBox.VertScrollBar.Range properties so they do not scroll far enough to see the TRadioGroup's right and bottom borders.
This way, the buttons appear as if they are part of the TGroupBox, but with the added scrollbar(s).
RadioGroup->Items->Count
TRadioGroup component doesn't have an embedded scrollbar, but you can put the radio group on a TScrollBox for a similar effect.
You can use the Buttons collection to refer each button, e.g.
RadioGroup->Buttons[0]->Height = 5;
RadioGroup->Buttons[1]->Top = RadioGroup->Buttons[0]->Top + 10;
Anyway a TComboBox could also be a good choice.