Qt - Get QPushButton icon name - c++

I have a two state QPushButton. I want to associate an icon to each state.
It is like Play|Pause buttons in music players.
To do so, I would like to get the current icon name in order to know what the next icon to set will be.
I could subclass QPushButton but is it worth it?

Instead of setting an icon based on the QPushButton's state, set one QIcon that has two states, Qt will select the correct icon if you use it with a checkable QPushButton.
QIcon icon = QIcon();
// 'Off' state corresponds to unchecked state of QPushButton
icon.addPixmap( QPixmap( ":/img/play.png" ), QIcon::Normal, QIcon::Off );
// 'On' state corresponds to checked state of QPushButton
icon.addPixmap( QPixmap( ":/img/pause.png" ), QIcon::Normal, QIcon::On );
QPushButton * button = new QPushButton();
button->setIcon( icon );
button->setCheckable( true );

Use QPushButton::icon() and QIcon::name() to get the icon name.

Related

Qt5/C++: change style of a QIcon inside a QToolBar

I'm adding actions to a QToolBar only using icons and an empty text, and I want to change each action style when it is triggered (specifically, changing its border color):
toolbar = new QToolBar;
action1 = toolbar->addAction(my_icon1, "");
action2 = toolbar->addAction(my_icon2, "");
QObject::connect(action1, &QAction::triggered, [this]{
// change border color of action1
// unset border color of action2
});
QObject::connect(action2, &QAction::triggered, [this]{
// change border color of action2
// unset border color of action1
});
But since a QIcon is not a widget (not a QAction of course), I don't know where to set the style of a specific action, and QAction::associatedWidget() returns the QToolBar widget and not the associated button that owns the icon.
I'm using only C++ code, without QML or ui files.
Since QAction::parentWidget and QAction::associatedWidgets both contain the QToolBar instead of the actual action widget, I didn't give initial credit to QToolBar::widgetForAction (I thought it would be some kind of convenient function for the QAction:: methods above). But it deserves it, because it returns the actual widget for that action, as the function name says:
toolbar->widgetForAction(action1)->setStyleSheet
("QWidget { border: 1px solid blue; }");

How to know parent menu of a given QAction?

I have a list of QActions, some are added to the top level menu and few are added to submenus of top level.
Is there any way to know parent menu name of each actions?
QAction *act;
I'm trying act->parentWidget(). But how can I get menu name from this?
You can check if the result of act->parentWidget() if it is a valid pointer, if so you can manipulate as a normal widget.
To get the menu name, it depends on which widget you are using.
If is QMenu, you can retrieve the menu title via the title function.
QAction *act;
...
QWidget *widget = act->parentWidget();
if (widget) {
QMenu *menu = dynamic_cast<QMenu*>(widget);
menu->title();
}

drop shadow effect on QPushButton text

How do I set a drop-shadow effect on a QPushButton text?
I could set shadow on the entire QPushButton using QGraphicsDropShadowEffect, I however, am not able to find a way to directly set the effect of text inside the QButton.
Edit:
I tried the following, not sure if the syntax is correct
in the .qss file:
MyButton::text
{
shadow: palette(dark);
}
I set the button's drop shadow effect by:
QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect( );
effect->setBlurRadius( 5 );
mStartButton->setGraphicsEffect( effect );
Try this:
Set a QLabel iside QPushButton rather than simple text. Then apply shadow effect to the label.
You may need to add extra code for centering the label inside the pushbutton.
mStartButton->setText("");
QLabel *label = new QLabel(mStartButton);
label->setText("<b>Button</b>");
QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect( );
effect->setBlurRadius( 5 );
label ->setGraphicsEffect( effect );

Qt: How to display selected text in an inactive window

I have an inactive QMainWindow with a QTabWidget as CentralWidget which holds multiple QPlainTextEdits. Beside that I have a seperate QWidget flagged with Qt::WindowStaysOnTopHint and Qt::Tool which I want to use as a find/replace tool for the QPlainTextEdits.
Now when I use the tool widget the QMainWindow is shown as inactive like it should and the selection background of the selected text in the active QPlainTextEdit is rendered as inactive (slightly grey) but I want the selection to be rendered like the QMainWindow would be active, with the default selection color w/o loosing the focus on the tool widget.
How do I achieve that?
Try something this:
QPalette p = myInactiveWidget->palette();
for (int colorRole=0; colorRole<QPalette::NColorRoles; colorRole++) p.setColor(QPalette::Inactive, colorRole, p.color(QPalette::Active, colorRole));
myInactiveWidget->setPalette(p);
That should make (myInactiveWidget)'s inactive-color-palette the same as its active-color-palette, so that it no longer looks inactive. Or if all you care about is the color of the text-selection-block, then this would probably be sufficient:
QPalette p = myInactiveWidget->palette();
p.setColor(QPalette::Inactive, QPalette::Highlight, p.color(QPalette::Active, QPalette::Highlight));
p.setColor(QPalette::Inactive, QPalette::HighlightedText, p.color(QPalette::Active, QPalette::HighlightedText));
myInactiveWidget->setPalette(p);

Disabling a QCheckbox in a tricky way

I want to make a QCheckBox named "Show Captions" disable another QCheckBox named "Show captions if no title" when the first is checked, but my problem is that how I can make it disabled immediately when the user checks the first checkbox.
SetupSlideShow::SetupSlideShow(QWidget* parent)
: QScrollArea(parent), d(new SetupSlideShowPriv)
{
QWidget* panel = new QWidget(viewport());
setWidget(panel);
setWidgetResizable(true);
QVBoxLayout* layout = new QVBoxLayout(panel);
d->showComment = new QCheckBox(i18n("Show captions"), panel);
d->showComment->setWhatsThis( i18n("Show the image caption at the bottom of the screen."));
d->showTitle = new QGroupBox(i18n("Show title"), panel);
d->showTitle->setWhatsThis( i18n("Show the image title at the bottom of the screen."));
d->showTitle->setCheckable(true);
d->showCapIfNoTitle = new QCheckBox(i18n("Show captions if no title"), panel);
d->showCapIfNoTitle->setWhatsThis( i18n("Show the image caption at the bottom of the screen if no titles existed."));
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(d->showCapIfNoTitle);
d->showTitle->setLayout(vbox);
layout->addWidget(d->showLabels);
layout->addWidget(d->showComment);
layout->addWidget(d->showTitle);
}
Doesn't this work?
connect(d->showComment, SIGNAL(toggled(bool)), d->showCapIfNoTitle, SLOT(setDisabled(bool)));
The call to paintEvent() isn't really doing anything for you regarding immediacy. Nothing will be repainted until control returns to the event loop (after your constructor exits). It is more typical to call update() but even this is unnecessary when changing the properties of built in widgets.
To link the check boxes, define a slot for the stateChanged() signal of showComment, connect the signal to your slot in your constructor above (by calling connect(), and in that slot, call d->showCapIfNoTitle->setCheckState(d->showComment->checkState()).