TaiZzZ
TaiZzZ

Reputation: 63

Adjusting Font size - Font Property

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

Answers (1)

Gabrielle de Grimouard
Gabrielle de Grimouard

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

Related Questions