From 10:00 CET Friday 22nd November we will adjust how the server works to deal with some recently reported problems. Therefore there may be a load problem, if you experience more problems than usual trying to access the forum then please PM AndyS or any of the moderators so they can inform me.


Can we use CSS on QPushButton




  • Moderators

    @Swapnil_Shelke I don't think you get full CSS but there is quite a bit. Check out the documentation like http://doc.qt.io/qt-5/stylesheet-syntax.html for more information.


  • Moderators

    @Swapnil_Shelke
    I'm not sure, but I don't think animation is supported in QT's StyleSheet,maybe someone can correct me here.

    What you could do is subclass QPushButton and define a bunch in intermediate state properties and define each one in the css. Than in the class, start a timer on button pressed that set the states to true, one after the other.

    A lot of work but this should do it...



  • @Swapnil_Shelke

    Maybe you would have a look at the Animation Framework.



  • Hi @Swapnil_Shelke

    Stylesheet is available with qt

    http://doc.qt.io/qt-5/stylesheet-syntax.html

    But Animations properties are not available with qt

    You can use stylesheet , add Q_PROPERTY and then

    Animate this Q_PROPERTY with the qt animation framework:

    http://doc.qt.io/qt-5.8/animation-overview.html

    You can look at the first answer of this post:

    http://stackoverflow.com/questions/34445507/change-background-color-of-qwidget-using-animation

    Or instead of using stylesheet, i think that you can use

    QGraphicsEffect

    http://doc.qt.io/qt-5/qgraphicseffect.html

    I think that you will need to use the
    http://doc.qt.io/qt-5/qgraphicsopacityeffect.html

    For you example

    and then animate this effect with the qt animation framework

    http://stackoverflow.com/questions/19087822/how-to-make-qt-widgets-fade-in-or-fade-out

    Hope this can help !



  • @Swapnil_Shelke
    To create those kind of buttons you need more than CSS.
    You must go into button's paintEvent and then draw what you need (there are 3 simultaneous animation BTW) :

    #include <QtCore/qvariantanimation.h>
    #include <QtCore/qvariant.h>
    #include <QtWidgets/qabstractbutton.h>
    #include <QtWidgets/qapplication.h>
    #include <QtWidgets/qlayout.h>
    
    class Animation : public QVariantAnimation {
    	Q_OBJECT
    
    public:
    	Animation(QObject *parent = 0) :QVariantAnimation(parent) {
    		setTargetWidget(qobject_cast<QWidget*>(parent));
    		setAutoUpdateEnable(true);
    	}
    
    	void setAutoUpdateEnable(bool a) {
    		if (targetWidget()) {
    			a ? QObject::connect(this, SIGNAL(valueChanged(QVariant)), targetWidget(), SLOT(update()))
    				: QObject::disconnect(this, SIGNAL(valueChanged(QVariant)), targetWidget(), SLOT(update()));
    		}
    	}
    
    	QWidget *targetWidget() const {
    		return _target;
    	}
    	void setTargetWidget(QWidget *w) {
    		_target = w;
    	}
    
    	QVariant value() const {
    		return _value;
    	}
    	void setValue(const QVariant &variant) {
    		if (_value == variant) return;
    		_value = variant;
    	}
    
    protected:
    	void updateCurrentValue(const QVariant &value) override {
    		setValue(value);
    	}
    
    private:
    	QVariant _value;
    	QWidget *_target = nullptr;
    };
    
    class SampleButton :public QAbstractButton {
    public:
    	struct ButtonStyle {
    		qreal border_radius = 4.0;
    		QColor background_color = QColor("#f4511e");
    		QColor text_color = QColor("#ffffff");
    		int font_size = 28;
    		QString font_family = "Arial";
    		int width = 200;
    		int padding = 20;
    		qreal hover_padding = 25;
    		int duration = 600;
    		QIcon icon = QIcon("next.png"); // http://www.flaticon.com/free-icon/double-angle-pointing-to-right_25358 @16x16
    		qreal pixmap_padding = 20;
    	};
    
    	SampleButton(const QString &text, QWidget *parent = 0) :QAbstractButton(parent), _textEff(new Animation(this)), _pixmapEff0(new Animation(this)), _pixmapEff1(new Animation(this)) {
    		setFont(QFont(_st.font_family, _st.font_size));
    		setText(text);
    	}
    
    	QSize sizeHint() const override {
    		return QSize(_st.width, _st.padding + fontMetrics().height() + _st.padding);
    	}
    
    protected:
    	void paintEvent(QPaintEvent *) override {
    		QPainter p(this);
    
    		// draw background
    		p.setPen(Qt::NoPen);
    		p.setBrush(_st.background_color);
    		p.setRenderHint(QPainter::Antialiasing, true);
    		p.drawRoundedRect(rect(), _st.border_radius, _st.border_radius);
    		p.setRenderHint(QPainter::Antialiasing, false);
    
    		// draw text
    		if (!text().isEmpty()) {
    			p.setFont(font());
    			p.setPen(_st.text_color);
    			p.setRenderHint(QPainter::TextAntialiasing, true);
    			p.drawText(QRectF(rect().x() - _textEff->value().toReal(), rect().y(), rect().width(), rect().height()), Qt::AlignCenter, text());
    			p.setRenderHint(QPainter::TextAntialiasing, false);
    		}
    
    		// draw icon
    		if (!_st.icon.isNull()) {
    			p.setRenderHint(QPainter::SmoothPixmapTransform, true);
    			auto s = _st.icon.availableSizes().at(0);
    			p.setOpacity(_pixmapEff0->value().toReal());
    			p.drawPixmap(QPointF(rect().right() - (_st.pixmap_padding * 2) - _pixmapEff1->value().toReal(), rect().center().y() - s.width() / 4), _st.icon.pixmap(s));
    		}
    	}
    
    	void enterEvent(QEvent *e) {
    		_textEff->setStartValue(0.0);
    		_textEff->setEndValue(_st.hover_padding);
    		_textEff->setDuration(_st.duration);
    		_textEff->setEasingCurve(QEasingCurve::OutCubic);
    		_textEff->start();
    
    		_pixmapEff0->setStartValue(0.0);
    		_pixmapEff0->setEndValue(1.0);
    		_pixmapEff0->setDuration(_st.duration);
    		_pixmapEff0->setEasingCurve(_textEff->easingCurve());
    		_pixmapEff0->start();
    
    		_pixmapEff1->setStartValue(0.0);
    		_pixmapEff1->setEndValue(_st.pixmap_padding);
    		_pixmapEff1->setDuration(_st.duration);
    		_pixmapEff1->setEasingCurve(_textEff->easingCurve());
    		_pixmapEff1->start();
    		QWidget::enterEvent(e);
    	}
    
    	void leaveEvent(QEvent *e) {
    		_textEff->setStartValue(_st.hover_padding);
    		_textEff->setEndValue(0.0);
    		_textEff->setDuration(_st.duration);
    		_textEff->start();
    
    		_pixmapEff0->setStartValue(1.0);
    		_pixmapEff0->setEndValue(0.0);
    		_pixmapEff0->setDuration(_st.duration);
    		_pixmapEff0->start();
    
    		_pixmapEff1->setStartValue(_st.pixmap_padding);
    		_pixmapEff1->setEndValue(0.0);
    		_pixmapEff1->setDuration(_st.duration);
    		_pixmapEff1->setEasingCurve(_textEff->easingCurve());
    		_pixmapEff1->start();
    		QWidget::leaveEvent(e);
    	}
    
    private:
    	ButtonStyle _st;
    	Animation *_textEff = nullptr;
    	Animation *_pixmapEff0 = nullptr;
    	Animation *_pixmapEff1 = nullptr;
    };
    
    int main(int argc, char *argv[]) {
    	QApplication app(argc, argv);
    	QWidget *dialog = new QWidget;
    	dialog->setWindowFlags(Qt::FramelessWindowHint);
    	QHBoxLayout _Layout;
    	dialog->setLayout(&_Layout);
    	SampleButton *sb = new SampleButton("Hover");
    	_Layout.addWidget(sb);
    	dialog->show();
    	return app.exec();
    }
    
    #include "main.moc"
    

    enter image description here