Pemrograman Qt 14 – QPropertyAnimation untuk Animasi GUI


Bismillahirrahmanirrahim.

Tulisan ini tersedia dalam PDF.

qt-creator-logoUbiquity, program pemasang sistem operasi Ubuntu yang kita pakai selalu ketika menginstal, adalah sumber inspirasi program ini. Animasi berbentuk slider layaknya slider di web yang bergerak ketika tombol panah diklik, adalah sesuatu yang gagal diimplementasikan pada Otodidak versi 1. Kegagalan itu disebabkan oleh ketidaktahuan mengenai hard coding di Java terutama pemakaian animasi di dalamnya. Kini dengan Qt, animasi sliding seperti layaknya Ubiquity di Ubuntu serasa mudah untuk dibuat. Kita bisa membuat elemen-elemen GUI bergerak melalui klik tombol dengan memakai kelas animasi di dalam Qt. Salah satunya adalah QPropertyAnimation. Tulisan ini bukan hendak membuat implementasi Ubiquity versi Qt (karena belum mampu) melainkan hanya pengantar menuju ke sana. Semoga tulisan ini bermanfaat.

Spesifikasi Sistem

  • Ubuntu 12.04
  • Qt Creator 2.4.1
  • Qt 4.8.0 (32 bit)

Daftar Kelas

  • QPropertyAnimation

Daftar Method

  • setStartValue
  • setEndValue

Arah Tulisan Ini

Bayangkan Otodidak dengan antarmuka seperti Ubiquity. Itulah tujuan antarmuka aslinya Otodidak. Slider dalam Ubiquity itu mirip slider di web yang biasanya dibuat dengan jQuery atau Flash. Karena ketidaktahuan, maka antarmuka yang indah itu tidak dapat diimplementasikan. Mari mengingat kembali bagaimanakah Ubiquity dan bagaimanakah slider di web.

Ubiquity

ngite-keempatbelas-ubiquity

Web

ngite-keempatbelas-slider

Seperti itulah slider yang beranimasi. Tulisan ini hanya akan membuat animasinya tanpa fungsi-fungsi lain slider.

Kode

mainwindow.h

 #include

namespace ui {
 class MainWindow;
 };

class MainWindow : public QMainWindow
 {
 Q_OBJECT

public:
 explicit MainWindow(QWidget *parent = 0);

public slots:
 void animasi();

private:
 QPushButton *tombol_utama;
 QPushButton *tombol_anakan[5];
 QWidget *objek_yang_dianimasikan;
 QPropertyAnimation *objek_yang_menganimasikan;
 };
 

mainwindow.cpp

//ANIMA+
#include <mainwindow.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    this->setGeometry(333,333,333,333);

    QVBoxLayout *vlayout = new QVBoxLayout;
    tombol_utama = new QPushButton("TOMBOL \n UTAMA", this);
    objek_yang_dianimasikan = new QWidget(this);

    objek_yang_dianimasikan->setGeometry(QRect(QPoint(-111,99), QSize(99,199)));
    objek_yang_dianimasikan->setLayout(vlayout);
    objek_yang_dianimasikan->show();

    tombol_utama->setGeometry(QRect(QPoint(199,99), QSize(99,99)));

    for(int i=1; i<5; i++){
        tombol_anakan[i] = new QPushButton(tr("TOMBOL %1").arg(i+1));
        tombol_anakan[i]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        vlayout->addWidget(tombol_anakan[i]);
    }

    connect(tombol_utama, SIGNAL(clicked()), this, SLOT(animasi()));
}

void MainWindow::animasi(){
    QPropertyAnimation *objek_yang_menganimasikan = new QPropertyAnimation(objek_yang_dianimasikan, "geometry");
    objek_yang_menganimasikan->setDuration(1111);

    QRect posisiAwal(-111,99,99,199);
    QRect posisiAkhir(55,99,99,199);

    objek_yang_menganimasikan->setStartValue(posisiAwal);
    objek_yang_menganimasikan->setEndValue(posisiAkhir);
    objek_yang_menganimasikan->start();
}

Hasil

ngite-ketigabelas-gs

Mohon maaf, gambar animasi ini jelek. Saya tidak mau menggunakan video sedangkan GIF hanya mampu menerima sedikit warna. Saya pun menjadikan gambar ini grayscale.

Pembahasan

Pembahasan program kali ini mungkin yang terpanjang dibanding program-program sebelumnya. Ada banyak teknik baru yang perlu diperhatikan untuk membuat animasi sederhana di atas.

mainwindow.cpp

Ada banyak hal yang mesti diperhatikan. Saya membagi penjelasan kali ini menjadi paling penting dan kurang penting.

1. Paling Penting

Yang diperhatikan: QPropertyAnimation, QWidget, show(), setDuration, setStartValue, setEndValue.

1.1. Yang Dianimasi dan Yang Menganimasi

Inti program ini adalah menggerakkan QWidget dengan QPropertyAnimation. Dalam mainwindow.cpp, ada fungsi baru bernama animasi(). Animasi yang dilakukan berjenis motion tween. Di dalam fungsi inilah terdapat deklarasi objek QPropertyAnimation. Objek ini menggerakkan QWidget yang dibuat pada fungsi MainWindow() di atasnya, dengan method setStartLocation dan setEndLocation.

QPropertyAnimation *objek_yang_menganimasikan = new QPropertyAnimation(objek_yang_dianimasikan, "geometry");

Bentuk yang perlu diperhatikan adalah QPropertyAnimation( QObject, “geometry”). Jadi Anda bisa menggunakan QPushButton, QWidget, QLineEdit, maupun objek lain selama mereka adalah anak kelas QObject. Inilah langkah memasukkan objek untuk dianimasikan. Sedangkan parameter sebelahnya harus “geometry” seperti itu. Maaf, saya belum mampu menjelaskan dengan detail.

1.2. Durasi Animasi

Sebagaimana yang kita ketahui, motion tween perlu diatur durasinya sesuai kebutuhan. Maka durasi diatur oleh method setDuration(). Satuan yang dipakai adalah milisekon.

objek_yang_menganimasikan->setDuration(1111);
1.3. Posisi Awal dan Posisi Akhir

Setelah semua diatur, tentu animasi dilakukan dengan memanggil posisi awal dan akhir objek. Lalu dipanggillah method start() supaya animasi berjalan.

objek_yang_menganimasikan->setStartValue(posisiAwal);
objek_yang_menganimasikan->setEndValue(posisiAkhir);
objek_yang_menganimasikan->start();

Sekian saja bagian terpenting program ini.

2. Kurang Penting

Yang diperhatikan: QRect, QPoint, QSize, tr(), arg(i+1).

2.1. QRect, QPoint, QSize

Program ini memakai QRect untuk menentukan ukuran objek QMainWindow, QPushButton, dan QWidget. QRect bisa diperluas perhitungan ukurannya dengan menentukan dahulu satu titik koordinat dengan QPoint lalu ditentukan panjang dan lebarnya dengan QSize. Ini dilakukan dalam satu parameter.

2.2. tr() dan arg(i+1)

Dua method khas Qt ini dipakai untuk otomatisasi pembuatan nama tombol-tombol secara otomatis. Oleh karena ini, maka kita bisa membuat banyak tombol dengan 1 perulangan for() saja. Jika tidak memakai ini, kita harus membuat satu per satu tombol dengan menomorinya satu per satu juga.

tombol_anakan[i] = new QPushButton(tr("TOMBOL %1").arg(i+1));
2.3. QRect Koordinat Posisi

Bagaimana bisa diketahui oleh program, posisi awal dan posisi akhir? Tentu harus ditentukan dahulu. Hal ini dilakukan dengan menulis koordinat pada objek QRect.

QRect posisiAwal(-111,99,99,199);
QRect posisiAkhir(55,99,99,199);

Kesimpulan

  1. Animasi bisa dilakukan dengan QPropertyAnimation untuk menggerakkan QObject. 
  2. QPropertyAnimation menghasilkan animasi berjenis motion tween.

Unduh Kode Sumber

Program kali ini bernama Anima+. Silakan unduh dan buka di Qt Creator Anda.

  1. Alamat: http://otodidak.freeserver.me/tarball/Anima+.tar.gz
  2. Ukuran: 3 KB

Referensi

https://qt-project.org/forums/viewthread/22835/

2 thoughts on “Pemrograman Qt 14 – QPropertyAnimation untuk Animasi GUI

  1. imamurafadorux

    Asallamualaikum.wr.wb
    Kak Akbar
    Bagaimanakah menambahkan fungsi “Find dan Replace” dalam program notepad berikut:
    terima kasih

    #include “viral.h”

    viral::viral(QWidget *parent)
    : QWidget(parent)
    {
    setWindowTitle(“Writeboard”);
    edit=new QTextEdit(this);
    menubar=new QMenu(this);
    bar= new QMenuBar(this);

    //setStyleSheet(“* { background-color:rgb(25,0,2);color:rgb(255,255,255); padding: 7px}}”);
    bar->setMinimumWidth(2);
    lay=new QVBoxLayout(this);
    status=new QStatusBar(this);
    newfile1=new QAction((“&New”),this);
    connect(newfile1,SIGNAL(triggered()),this,SLOT(newfile()));
    open=new QAction((“&Open”),this);
    connect(open,SIGNAL(triggered()),this,SLOT(loadme()));
    save=new QAction((“&Save”),this);
    connect(save,SIGNAL(triggered()),this,SLOT(saveme()));
    saveAs=new QAction((“SaveAs”),this);
    connect(saveAs,SIGNAL(triggered()),this,SLOT(saveme()));
    exi=new QAction((“&Exit”),this);
    connect(exi,SIGNAL(triggered()),qApp,SLOT(quit()));
    un=new QAction((“&Undo”),this);
    connect(un,SIGNAL(triggered()),this,SLOT(undome()));
    re=new QAction((“&redo”),this);
    connect(re,SIGNAL(triggered()),this,SLOT(redome()));
    cutme=new QAction((“&Cut”),this);
    connect(cutme,SIGNAL(triggered()),this,SLOT(Cut()));
    copyme=new QAction((“&Copy”),this);
    connect(copyme,SIGNAL(triggered()),this,SLOT(Copy()));
    pasteme=new QAction((“&Paste”),this);
    connect(pasteme,SIGNAL(triggered()),this,SLOT(Paste()));
    mystatus=new QAction((“&Status Bar”),this);
    mystatus->setCheckable(1);
    connect(mystatus,SIGNAL(toggled(bool)),status,SLOT(setHidden(bool)));
    about=new QAction((“About App”),this);
    connect(about,SIGNAL(triggered()),this,SLOT(aboutme()));
    menubar=bar->addMenu(tr(“&File”));

    menubar1=bar->addMenu(tr(“&Edit”));//Adding new menu to menubar

    menubar2=bar->addMenu(tr(“&View”));

    menubar3=bar->addMenu(tr(“&About”));

    menubar->addAction(newfile1);
    menubar->addSeparator();
    menubar->addAction(open);
    menubar->addSeparator();//Adding separator between to menu items
    menubar->addAction(save);
    menubar->addAction(saveAs);
    menubar->addSeparator();
    menubar->addAction(exi);

    menubar1->addAction(un);
    menubar1->addAction(re);
    menubar1->addSeparator();
    menubar1->addAction(cutme);//Merging Action in menubar
    menubar1->addSeparator();
    menubar1->addAction(copyme);
    menubar1->addSeparator();
    menubar1->addAction(pasteme);

    menubar2->addAction(mystatus);

    menubar3->addAction(about);
    lay->addWidget(bar);

    lay->addWidget(edit);
    lay->addWidget(status);
    setLayout(lay);
    showMaximized();

    }

    viral::~viral()
    {

    }
    void viral::loadme()
    {
    QString filename = QFileDialog::getOpenFileName(this,tr(“Open File”),tr(“*.txt”));
    QFile file(filename);
    if (file.open(QIODevice::ReadOnly|QIODevice::Text)) {
    edit->setPlainText(QString::fromUtf8(file.readAll()));
    mFilePath = filename;
    status->showMessage(tr(“File successfully loaded.”), 3000);
    }
    }
    void viral::saveme()
    {
    if(mFilePath.isEmpty())
    saveFileAs();
    else
    saveFile(mFilePath);
    }
    void viral::saveFile(const QString &name)
    {
    QFile file(name);
    if (file.open(QIODevice::WriteOnly|QIODevice::Text))
    {
    file.write(edit->toPlainText().toUtf8());
    }
    status->showMessage(tr(“File successfully Saved.”), 3000);
    }
    void viral::saveFileAs()
    {
    mFilePath = QFileDialog::getSaveFileName(this,tr(“Save File”),tr(“.txt”));
    if(mFilePath.isEmpty())
    return;
    saveFile(mFilePath);
    status->showMessage(tr(“File Saved”), 3000);

    }
    bool viral::mayDiscardDocument()
    {
    if (edit->document()->isModified())
    {
    QString filename = mFilePath;
    if (filename.isEmpty()) filename = tr(“Unnamed”);
    if (QMessageBox::question(this, tr(“Save Document?”),tr(“You want to create a new document, but the “”changes in the current document ’%1’ have not “”been saved. How do you want to proceed?”),tr(“Save Document”), tr(“Cancel”)))
    {

    return false;
    }
    else
    {
    saveme();
    return true;

    }
    }
    }
    void viral::newfile()
    {
    if (!mayDiscardDocument()) return;
    edit->setPlainText(“”);
    mFilePath = “”;
    status->showMessage(tr(“New File created”),3000);
    }
    void viral::undome()
    {
    edit->document()->undo();
    }
    void viral::redome()
    {
    edit->document()->redo();
    }
    void viral::Cut()
    {
    edit->cut();
    status->showMessage(tr(“Text Cut”),3000);
    }
    void viral::Copy()
    {
    edit->copy();
    status->showMessage(tr(“Text Copied”),3000);
    }
    void viral::Paste()
    {
    edit->paste();
    status->showMessage(tr(“Text pasted”),3000);
    }
    void viral::aboutme()
    {
    QMessageBox::about(this, tr(“About Writeboard”),”Writeboard 1.0\n A Qt application\n”);
    }

    Balas
  2. Ping balik: [C++] Membuat Aplikasi Pengenalan Karakter dengan Qt Creator di Linux | RESTAVA

Dilarang menggunakan emotikon