Qwidget, how to highlight the widget under the cursor - c++

I have created some QLabel type of widgets in QT, and added that to a QToolbar. I want to highlight the particular widget which is under the cursor. I am unable to understand how do I do that. Can somebody please help ? I need this information on QT 4.
Thanks.

You have several possibilities.
First, as you subclass QLabel, you can handle mouse events directly in your class.
Make sure to use QWidget::setMouseTracking() to enable this.
In such scenario you can do whatever you want with your control but you will have to
override paint routine so that your class can draw itself in some specific way.
Unfortunately QLabel does not support "hover" style sheet state so that you cannot
do it easily with styles sheets. However, if you consider subclassing from QPushButton you can have this wonderful feature
so that with the help of CSS you get nice highliting effect.
For more info on style sheets in QT look here.
If subclassing QPushButton is fine for you, then look here.
Just make sure you also use hover state like in this simple example:
QPushButton:hover {
background-color: black;
}
QPushButton:hover {
background-color: white;
}
Example for the mouse events handling can be found here

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

Qt/C++ - Set background of disabled button?

I have all my buttons disabled in a grid, but for some, I'd like to change the background color. I'm trying:
_fieldButtons[0][0]->setStyleSheet("color: blue; background-color: blue;");
Where
QVector<QVector<QPushButton*> > _fieldButtons;
However, these buttons are all disabled, and only the text color gets changed:
How can I change the background, but not the text? Thank you!
UPDATE
I figured it's not working because the buttons are flat. How can I change flat button colors?
Two options:
Add border: none; to your stylesheet.
Use setAutoFillBackground(true) in conjunction with QPalette::Button
myButton->setFlat(true);
myButton->setAutoFillBackground(true);
QPalette pal = myButton->palette();
pal.setColor(QPalette::Button, QColor(Qt::blue));
myButton->setPalette(pal);
http://doc.qt.io/qt-5/qpushbutton.html#flat-prop
Try this:
myButton->setPalette(QColor("#124e6b"));
simply change the QColor to suit your use.
Or in Qt Creator you can right-click on the widget and select Change Style Sheet, as shown here:
Here you have two "Pseudo-States" in your control. For list of "Pseudo-States" refer below link.
http://doc.qt.io/qt-5/stylesheet-reference.html#list-of-pseudo-states
The first "Pseudo-State" is -- flat
The second "Pseudo-State" is -- disabled
Here you have to club both the states to set the style using "setStyleSheet".
_fieldButtons[0][0]->setStyleSheet(":flat:disabled {background-color: blue; border: none;}");
look for ":hover:enabled" (two different "Pseudo-States" how documentation handled) in the below link to get better idea.
http://doc.qt.io/qt-4.8/stylesheet-syntax.html
To understand, why you we have to give border:none for QPushButton, please look for below information in the first hyperlink in this answer.
"Warning: If you only set a background-color on a QPushButton, the background may not appear unless you set the border property to some value. This is because, by default, the QPushButton draws a native border which completely overlaps the background-color."

QT window within window?

I'm setting up a small code editor using QT and following this example. However, i'm curious on how to create windows within windows or widgets within widgets. I'm trying to achieve something similar to these:
http://i.stack.imgur.com/Vn8Ut.png
http://www.hanselman.com/blog/content/binary/Windows-Live-Writer/Download-Visual-Studio-2013-while-your-f_1431E/image_4eb5427c-1ae7-4464-9c26-2282fe8d06c3.png
Is there an example of overlaying widgets like this?
Any alternative soloution for QMessagebox for IOS development (QWidget application only)?
I gave an example of getting another QWidget to be embedded and painted on top of another one. Let me know if you have any questions about how it was done.
The PopUp flag and Qt::Tool options are also relevant.
Be sure to check out: the ToolTip property of a QWidget and the WhatsThis property of QWidget.
http://qt-project.org/doc/qt-5/qwidget.html#toolTip-prop
http://qt-project.org/doc/qt-5/qwidget.html#whatsThis-prop
There are also other ways to make borderless, focusless windows that hover and disappear quickly on command. The Window Flags and Widget Attributes in Qt are very powerful when you are looking to modify Qt Widgets.
When you parent a Widget to another widget, it will draw itself on top of the other. Then you just need to resize and position it properly.
Also subclassing existing widgets can give you more options.
Draw text on scrollbar
Also common Qt::Tools that you will find are QDockWidgets. They are awesome!
Hope that helps.
Take a look at Qt Namespace especially Qt::WA_LayoutOnEntireRect and Qt::WA_StyleSheet. Pass it as a widget attrybutes. The second option looks promising but you have to create style sheet for QWidget.

101 Qt stylesheet margins padding hack guide in C++. Setting padding doesn't work

After months of research and asking here, I found out the solution to make margins be reset to 0 and paddings to 0, stylize a widget and start from scratch a design using stylesheets in qt.
The widgets must be containers of something else.
101 Guide to style widgets margins/padding using stylesheets in qt4
Create any kind of BoxModel stylable widget (not QWidget, use QFrame instead!). Check documentation
Assign a normal layout to it.
If you don't want the default margins, which are big as apox. 8px more or less, you have to set the layout (not the widget, you can, but doesn't work) contents margin to 0: setContentsMargins(0,0,0,0).
Optionally (I don't know which cases), to bring everything to the extreme reset (no borders, nothing at all), set spacing to 0 too. setSpacing(0)
set the widget object name to a custom name: setObjectName("name").
set your style changing QFrame by your widget: QFrame#name { things... }
If you want to stylize the custom widget and you have a custom class name for it, and you intend to use the NAME of the class instead of using setObjectName, add this small hack reimplementing your paint method, which is included in Qt Stylesheet documentation example.
If you subclass from QWidget, you need to provide a paintEvent for
your custom QWidget as below:
void CustomWidget::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
The above code is a no-operation if there is no stylesheet set.
Warning: Make sure you define the Q_OBJECT macro for your custom
widget.
Then you can create the style by using the class name. ClassName {}
Now, I have a serious problem which I shared with other people and I had no solution. Padding doesn't work at all. Only margins work.
So
ClassName
{ padding: 200px; margin: 5px; }
does the same as
ClassName
{ margin: 5px; }
That brings the bothering situation when you have to create subcontainers with margins to add a padding. That brings us to an infinite hierarchy... Which is not desirable at all.
Does anybody know how to completely finish my 101 guide?
Padding works
My problem comes from the class I used for checking that padding didn't work. It was a subclass of QWidget, which, as documentation clearly says:
Supports only the background, background-clip and background-origin
properties.
So my background property was working and I didn't understand why padding didn't.
So I answered my own question without knowing it.