Reputation: 63
I have a QPushButton
designed with css.
I wanted him to change size on clicked. I used a QPropertyAnimation(mybutton,"geometry")
to achieve this goal.
Yet, the size policy is fixed. To adjust this factor, I would like to use the font property of a QPushButton.
class MyButton : public QPushButton
{
Q_OBJECT
public:
explicit MyButton(QWidget *parent = Q_NULLPTR);
~MyButton();
};
And my .ccp
:
MyButton::MyButton(QWidget *parent) : QPushButton(parent)
{
this->setGeometry(150,20,340,50);
this->setStyleSheet("border-radius: 25; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #eeeeee, stop: 1 #5F6060);");
this->setText("Menu");
this->setFont(QFont("Colibri",25));
this->setCursor(Qt::PointingHandCursor);
QPalette pal;
pal.setColor(QPalette::ButtonText,Qt::white);
this->setPalette(pal);
}
I try to animate using QPropertyAnimation
as follows :
animationBoutonMenuText = new QPropertyAnimation(myButton,"font");
animationBoutonMenuText->setDuration(300);
animationBoutonMenuText->setKeyValueAt(0,QFont("Colibri",25));
animationBoutonMenuText->setKeyValueAt(0.5,QFont("Colibri",30));
animationBoutonMenuText->setKeyValueAt(1,QFont("Colibri",25));
animationBoutonMenuText->start();
But it doesn't work. It resets my font size on click (I guess the default value is 10 or 11 pixels) and it stays at the default size. Do you have any idea why ?
Ps : I've seen this, but those css
tags seems not to work on Qt. Am I wrong ?
This leads to another question (sorry), can we modify (meaning use the Q_PROPERTY
macro) css factors ? Such as border-radius
, which should change with the size of my button.
EDIT :
#include "mybutton.h"
QVariant myFontInterpolator(const QFont &start, const QFont &end, qreal progress)
{
int a = start.pixelSize();
int b = end.pixelSize();
int c = (1-progress)*a + progress*b;
QFont rt(start);
rt.setPointSize(c);
return (rt);
}
MyButton::MyButton(QWidget *parent) : QPushButton(parent)
{
this->setGeometry(150,20,340,50);
this->setStyleSheet("border-radius: 25; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #eeeeee, stop: 1 #5F6060);");
this->setText("Menu");
this->setFont(QFont("Colibri",25));
this->setCursor(Qt::PointingHandCursor);
qRegisterAnimationInterpolator<QFont>(myFontInterpolator);
QPalette pal;
pal.setColor(QPalette::ButtonText,Qt::white);
this->setPalette(pal);
}
MyButton::~MyButton()
{
}
EDIT 2 (piece of code to get the behaviour I wanted) :
QVariant myFontInterpolator(const QFont &start, const QFont &end, qreal progress)
{
if (progress<0.5)
{
int a = (1-progress)*25 + progress*30;
QFont rt(start);
rt.setPointSize(a);
return rt;
}
else
{
int a = (1-progress)*30 + progress*25;
QFont rt(start);
rt.setPointSize(a);
return rt;
}
}
And the animation :
animationBoutonMenuText = new QPropertyAnimation(boutonMenu,"font");
animationBoutonMenuText->setDuration(300);
animationBoutonMenuText->setStartValue(QFont("Colibri",25));
animationBoutonMenuText->setEndValue(QFont("Colibri",25));
animationBoutonMenuText->start();
Upvotes: 1
Views: 369
Reputation: 2005
There are some things that are not correct in your code and that's why it's not working as you expect. First, the QFont is not in the list of QVariantAnimation, that means you cannot do animation with QPropertyAnimation and QFont like you do. here the list of possible properties.
However, you can create an interpolator to make it work. Like that (it's in the same page than the previous link).
Not all QVariant types are supported. Below is a list of currently supported QVariant types:
Int UInt Double Float QLine QLineF QPoint QPointF QSize QSizeF QRect QRectF QColor
If you need to interpolate other variant types, including custom types, you have to implement interpolation for these yourself. To do this, you can register an interpolator function for a given type. This function takes 3 parameters: the start value, the end value, and the current progress.
Example:
QVariant myColorInterpolator(const QColor &start, const QColor &end, qreal progress) { ... return QColor(...); } ... qRegisterAnimationInterpolator(myColorInterpolator);
Another option is to reimplement interpolated(), which returns interpolation values for the value being interpolated.
Your border-radius is too big, with a value of 15, there is a good border-radius. So here a small code with an animation that works (but does not do exactly what you want).
test.pro:
#-------------------------------------------------
#
# Project created by QtCreator 2017-06-26T12:49:54
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp\
mainwindow.cpp \
mybutton.cpp
HEADERS += mainwindow.h \
mybutton.h
FORMS += mainwindow.ui
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mybutton.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
auto myButton = new MyButton(this);
ui->verticalLayout_2->addWidget(myButton);
}
MainWindow::~MainWindow()
{
delete ui;
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mybutton.cpp:
#include "mybutton.h"
#include <QPropertyAnimation>
#include <QDebug>
QVariant myFontInterpolator(const QFont &start, const QFont &end, qreal progress)
{
int a = start.pixelSize();
int b = end.pixelSize();
int c = (1-progress)*a + progress*b;
QFont rt(start);
rt.setPointSize(rt.pointSize() - c);
return (rt);
}
MyButton::MyButton(QWidget *parent) : QPushButton(parent)
{
this->setGeometry(150,20,340,50);
this->setStyleSheet("background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #eeeeee, stop: 1 #5F6060); border-radius: 19;");
this->setText("Menu");
this->setFont(QFont("Colibri", 25));
this->setCursor(Qt::PointingHandCursor); // Marche que au début (si on est pas passé au dessus d'autre chose)
qRegisterAnimationInterpolator<QFont>(myFontInterpolator);
QPalette pal;
pal.setColor(QPalette::ButtonText,Qt::white);
this->setPalette(pal);
}
void MyButton::mousePressEvent(QMouseEvent *ev)
{
auto animationBoutonMenuText = new QPropertyAnimation(this,"font");
animationBoutonMenuText->setDuration(300);
animationBoutonMenuText->setKeyValueAt(0,QFont("Colibri",25));
animationBoutonMenuText->setKeyValueAt(0.5,QFont("Colibri",30));
animationBoutonMenuText->setKeyValueAt(1,QFont("Colibri",25));
animationBoutonMenuText->start();
}
mybutton.h:
#ifndef MYBUTTON_H
#define MYBUTTON_H
#include <QPushButton>
class MyButton : public QPushButton
{
Q_OBJECT
public:
explicit MyButton(QWidget *parent = Q_NULLPTR);
~MyButton() {}
public slots:
void mousePressEvent(QMouseEvent *ev);
};
#endif // MYBUTTON_H
EDIT: the mybutton.cpp has been updated with a font that change with the animation. I am not sure it's the animation you seek but you can start with it.
Upvotes: 1