How to gray a group of widgets when they are disabled? - qt

There is a QGroupBox full of widgets, and all of them need to be disabled and grayed out.
setDisabled(true) does disable them functionally, but they don't turn gray.
What is the easiest and most proper way to turn them gray?
This should be a standard operation: text turns gray so that users can easily see that they are disabled.

QWidget::setDisabled() is yet (another) slot for the QWidget enabled property.
From Qt doc.:
This property holds whether the widget is enabled
In general an enabled widget handles keyboard and mouse events; a disabled widget does not. An exception is made with QAbstractButton.
Some widgets display themselves differently when they are disabled. For example a button might draw its label grayed out.
(Emphasizing by me.)
How widgets are displayed depends on their respective rendering as well as the (default) QStyle which is used in the application.
Concerning custom widgets (classes derived from any "built-in" Qt widget) where paintEvent() is overloaded, the custom widget is itself responsible to render accordingly to different states.

Related

Enable blinking cursor in QML TextInput object

I have to work with a code with custom touch numpad/keyboard implementation. The input field is based on TextInput object and I can achieve the 'static' cursor by modifying its direct members
textInput.cursorVisiblity=true
textInput.cursorPosition=val
It works fine, but the cursor is not blinking.
After some research I find out the solution by calling the method:
inputVal.forceActiveFocus()
It gives me proper blinking cursor, but also provides default keyboard panel which overrides the custom one.
I'd like to somehow turn on only this blinking cursor or at least somehow block the additional keyboard panel
It turned out that there were defined some global virtual keyboard that I had to disable

Is there a way to show tooltip on disabled QWidget

I have a Qt form, where I have a button and menu. For various reasons I can disable certain elements, e.g button or some actions in the menu.
Is there a way I could show a tooltip or when the mouse is hovered over the disabled button or menu item with an explanation as to why it is disabled?
I am using Qt 4.8.
Thanks!
You can set the tooltip dynamically based on the state of the QWidget or by simply toggling both at the same time. Upon disabling/enabling the widget from somewhere just call QWidget::setToolTip(...) with the QString you want the tooltip to display when hovering with the mouse over the given widget. For example if you have a public slot called toggleButton(bool toggleFlag) which toggles the enable-setting of a button you can do:
void MyWidget::toggleButton(bool toggleFlag) {
this->ui->myButton->setEnabled(toggleFlag);
this->ui->myButton->setToolTip(toggleFlag ? QString("Enabled wohoo!") : QString("Disabled because I like it"));
}
You can of course do also change the tooltip by calling QWidget::isEnabled() and act upon its return value. Since you haven't given any code I can only assume how you toggle your button(s) so that's all I can give you for now.
UPDATE: It was pointed in the comments that tooltips don't work with disabled widgets due not receiving mouse events. Both statements are not true (note that I have used the same tooltip message since due to lack of minimal working example I didn't want to write a whole new project from scratch and used an existing one of mine instead):
Hovering a disabled button triggers the tooltip
Hovering an enabled button triggers the tooltip

How can I disable a Qt widget without changing its appearence

I have a Qt widget which has a layout and there are more widgets inside it. When I disable the widget the whole widget becomes little faded and no modifications are possible anymore. I want the features that comes with disabling a widget but I do not want it's appearance to change. Please let me know how this can be done.
Few ideas that comes to my mind:
Rather disabling widget, capture all the events on the widget and do nothing
Update style sheet for disabled state (not sure if possible)
1. Capture events
Use QObject::installEventFilter() and QObject::eventfilter().
Keep in mind the way Qt dispatch GUI events, in particular children get events first. So you need to install the event filter recursively on all widgets and watch for QEvent::ChildAdded.
2. Using stylesheets
This is a not a good solution. Stylesheets tend to break QStyle mechanisms which may lead to side effects.
3. Use a QPixmap
Hide all the child widgets, render them to a QPixmap and draw the pixmap in the paintEvent.

Qt: Change the icon in a QListView

Is there a way to change the icon of an element in a QListView after it has been displayed?
I can't find a way to do a setData with the DecorationRole (the role used for the icon).
The model used is a custom QFileSystemModel, but the default implementation is only good for the EditRole so to change the name of the item.
I'm don't know how the the overridden setData can be done.
The goal is to change the icon when the mouse is over the item (through mouseMoveEvent)
You will need to subclass QListView and implement the behavior that changes the role of the displayed icon when the mouse hovers over the item.
Such a subclass could use an internal proxy model so that it wouldn't need to mess with the base view's painting. Simply inform the proxy that a given item's decoration role data has changed, and the base view will know what to do.

How to make a QSlider read-only?

Using Qt 5.2.1
Is it possible to set a QSlider (doesn't matter if it's horizontal or vertical) to read-only that is user cannot change the value of the slider but only use it as an indicator of some sort? I was unable to find anything in the Qt documentation or the Qt Designer.
Example for application: displaying a binary state of some sort in the GUI (in my case is the emergency stop on or off).
AFAIK such feature is not available in the QSlider implementation.
However, you can create your own class deriving from QSlider and implement the desired behavior by overwriting mousePressEvent, mouseReleaseEvent, mouseMoveEvent, keyPressEvent and keyReleaseEvent and only call the respective parent implementation if the readOnly property is set to false.
Luckily, such an implementation is already available in kalarm, so have a look at it: http://api.kde.org/4.6-api/kdepim-apidocs/kalarm/lib/html/slider_8cpp_source.html
Maybe a QProgressBar would be more suitable since users know it as "read only" and "shows how much has been done".
Following kuba ubar's second approach -
Suppose the object name of your slider is horizontalSlider. Then the code should be
// getting the palette of the slider
QPalette _sliderPalette = ui->horizontalSlider->palette();
// changing the colorGroup of that palette
_sliderPalette.setCurrentColorGroup(QPalette::Active);
// setting the changed palette to the slider
ui->horizontalSlider->setPalette(_sliderPalette);
One simple solution would be to install an event filter on the slider that consumes all mouse, focus and keyboard events. You'd also need to make the slider have a Qt::NoFocus policy. Such an event filter would be universal and could be used with any control widget.
An alternative would be to disable the widget, and style it so that the disabled and enabled palette are the same. This might not work with some of the platform styles, though, and would need experimental verification before you commit to it.

Resources