Pemrograman Qt 17 – Pan, Scroll, Zoom, Flip, dan Rotate untuk QGraphicsView


Bismillahirrahmanirrahim.

Tulisan ini tersedia dalam PDF

qt-creator-logoTulisan ini adalah kelanjutan dari tutorial sebelumnya dalam hal QGraphicsScene dan QGraphicsView. Kita akan membuat sebuah image viewer yang mampu melakukan pan, scroll, zoom in, zoom out, flip, dan rotate. Anda dapat mengunduh kode sumber program berupa proyek Qt Creator di bagian akhir tulisan. Semoga tulisan ini bermanfaat.

Spesifikasi Sistem

  • Ubuntu 12.04
  • Qt Creator 2.4.1
  • Qt 4.8

Daftar Kelas

  • QGraphicsScene
  • QGraphicsView
  • QToolButton
  • QVBoxLayout
  • QHBoxLayout
  • QWidget

Daftar Method

  • setSceneRect() -> milik QGraphicsScene
  • addPixmap() -> milik QGraphicsScene
  • setScene() -> milik QGraphicsView
  • setDragMode() -> milik QGraphicsView
  • scale() -> milik QGraphicsView
  • rotate() -> milik QGraphicsView
  • resetTransform() -> milik QGraphicsView
  • zoomin() -> buatan sendiri
  • zoomout() -> buatan sendiri
  • reset() -> buatan sendiri
  • rotate() -> buatan sendiri
  • flip() -> buatan sendiri

Arah Tulisan Ini

wavemon39

Kode

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

//#include
#include

namespace Ui {
class MainWindow;
}

//extern int pengubah_angka = 0;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QToolButton     *tombol_KDE;
    QToolButton     *tombol_GNOME;
    QToolButton     *tombol_XFCE;
    QToolButton     *tombol_LXDE;
    QToolButton     *tombol_UNITY;

    QGraphicsScene  *objek_QGS;
    QGraphicsView   *objek_QGV;

    QVBoxLayout     *layout_utama;
    QHBoxLayout     *layout_isi_global;
    QVBoxLayout     *layout_kiri_gambar;
    QVBoxLayout     *layout_kanan_tombol;

    QWidget         *fondasi;
    QWidget         *panel_kiri;
    QWidget         *panel_kanan;
    QPixmap         *pixmap;

//    double          scaleFactor;

public slots:
    void            zoomin();
    void            zoomout();
    void            flip_horizontal();
    void            flip_vertikal();
    void            rotate();
    void            reset();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    QToolButton *tombol_zoomin               = new QToolButton;
    QToolButton *tombol_zoomout              = new QToolButton;
    QToolButton *tombol_rotate               = new QToolButton;
    QToolButton *tombol_reset                = new QToolButton;
    QToolButton *tombol_flip_horizontal      = new QToolButton;
    QToolButton *tombol_flip_vertikal        = new QToolButton;

                objek_QGS = new QGraphicsScene;
                objek_QGV = new QGraphicsView;  //inilah QGV yang dipangkas yang dimaksud di komentar fungsi-fungsi di bawah

    QHBoxLayout *layout_utama = new QHBoxLayout;
    QVBoxLayout *layout_kiri_gambar = new QVBoxLayout;
    QVBoxLayout *layout_kanan_tombol = new QVBoxLayout;

    QWidget     *fondasi      = new QWidget;    //deklarasi objek di CPP harus normal
    QWidget     *panel_kanan  = new QWidget;    //sama sekali tidak boleh diringkas
    QWidget     *panel_kiri   = new QWidget;    //atau, segmentation fault

                pixmap = new QPixmap(":/gambar/ubuntu");    //deklarasi terpotong supaya bisa dipakai di fungsi luar buatan sendiri
                                                            //dan nanti kalau objek pixmap dipanggil di suatu fungsi sebagai
                                                            //parameter, maka dipanggil dengan didahului *

    //coba mengisi layout dengan QGV dan tombol

    layout_kanan_tombol->addWidget(tombol_zoomin);     //sisi kanan
    layout_kanan_tombol->addWidget(tombol_zoomout);
    layout_kanan_tombol->addWidget(tombol_rotate);
    layout_kanan_tombol->addWidget(tombol_reset);
    layout_kanan_tombol->addWidget(tombol_flip_horizontal);
    layout_kanan_tombol->addWidget(tombol_flip_vertikal);

    layout_kiri_gambar->addWidget(objek_QGV);       //sisi kiri

    //sekarang coba atur ukuran minimal para tombol

    tombol_zoomin->setMinimumSize(140,55);
    tombol_zoomout->setMinimumSize(140,55);
    tombol_rotate->setMinimumSize(140,55);
    tombol_reset->setMinimumSize(140,55);
    tombol_flip_horizontal->setMinimumSize(140,55);
    tombol_flip_vertikal->setMinimumSize(140,55);

    //sekarang coba beri nama untuk para tombol

    tombol_zoomin->setText("ZOOM IN");
    tombol_zoomout->setText("ZOOM OUT");
    tombol_rotate->setText("ROTATE");
    tombol_reset->setText("RESET");
    tombol_flip_horizontal->setText("FLIP  HORIZONTALLY");
    tombol_flip_vertikal->setText("FLIP  VERTICALLY");

    //coba memasang layout ke widget

    panel_kiri->setLayout(layout_kiri_gambar);
    panel_kanan->setLayout(layout_kanan_tombol);

    //coba membangun semua layout dulu sekaligus lalu diletakkan objek-objek pada tempatnya sesudahnya

    layout_utama->addWidget(panel_kiri);   //widget panel kiri
    layout_utama->addWidget(panel_kanan);  //widget panel kanan

    //tunggu, kita harus mengurus QGraphics* dulu

    objek_QGS->addPixmap(*pixmap);             //kalau suatu objek dideklarasikan dengan cara terpotong seperti baris 25 di atas
                                               //maka bentuk pemanggilan objek di dalam parameter harus diawali dengan *
                                               //ditemukan pada Yaum al-Arbi'a, Jumaada al-Awal 17, 1435 12:55 PM
                                               //Wednesday, March 19, 2014
                                               //tidak diawali dengan &, tidak diakhiri dengan & atau *

    objek_QGS->setSceneRect(QRectF(0,0,1,1));  //akhirnya setelah berjam-jam ketemu juga
                                               //sumber: http://www.qtcentre.org/threads/22372-QGraphicsScene-Scrollbar-resizing
                                               //ditemukan pada Yaum al-Khamees, Rabi` al-Thaani 19, 1435 11:06 PM / Thursday, February 20, 2014
                                               //gunanya baris ini untuk memaksa sisi kiri gambar tepat sisi kiri QGV, alias
                                               //supaya semua scrollbar selalu berada pada posisi paling awal / default
                                               //jika tidak begini, semua scrollbar selalu berada pada akhir posisinya
                                               //scrollbar nakal jika ukuran resolusi gambar melampaui ukuran QGV
    objek_QGV->setScene(objek_QGS);
    objek_QGV->setInteractive(true);
    objek_QGS->setSceneRect(0,0,pixmap->width(),pixmap->height());  //get image size macam ini saya peroleh dari stackoverflow tapi lupa alamatnya
                                                                  //ini harus ada setelah QRectF di atas
    objek_QGV->setDragMode(QGraphicsView::ScrollHandDrag);
    objek_QGV->show();

    //waktunya merender fondasi
    fondasi->setLayout(layout_utama);
    this->setCentralWidget(fondasi);

    //waktunya mainkan tombol untuk fungsi zoom | Yaum al-Khamees, Rabi` al-Thaani 19, 1435 11:27 PM
    connect(tombol_zoomin,   SIGNAL(clicked()),  this,  SLOT(zoomin()));
    connect(tombol_zoomout,  SIGNAL(clicked()),  this,  SLOT(zoomout()));
    connect(tombol_reset,    SIGNAL(clicked()),  this,  SLOT(reset()));
    connect(tombol_rotate,   SIGNAL(clicked()),  this,  SLOT(rotate()));
    connect(tombol_flip_horizontal,     SIGNAL(clicked()),  this,  SLOT(flip_horizontal()));
    connect(tombol_flip_vertikal,     SIGNAL(clicked()),  this,  SLOT(flip_vertikal()));

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::zoomin()
{
    double scaleFactor = 1.25;
    //kalau mau jalankan fungsi yang menembak langsung objek di dalam kelas utama,
    //maka deklarasi objek kelas yang ditembak harus dipangkas
    //lihat deklarasi QGV di atas
    //diingat kembali pada Yaum al-Ahad, Rabi` al-Thaani 22, 1435 01:13 PM dari Pemrograman Qt 5
//    this->objek_QGV->scale(scaleFactor,scaleFactor);
//    QTransform flip;
    this->objek_QGV->scale(scaleFactor, scaleFactor);

}

void MainWindow::zoomout()
{
    //kalau mau jalankan fungsi yang menembak langsung objek di dalam kelas utama,
    //maka deklarasi objek kelas yang ditembak harus dipangkas
    //lihat deklarasi QGV di atas
    //diingat kembali pada Yaum al-Ahad, Rabi` al-Thaani 22, 1435 01:13 PM dari Pemrograman Qt 5

    double      scaleFactor = 1.3;  //istimewa pada Yaum al-Ahad, Rabi` al-Thaani 22, 1435 01:33 PM
                                     //didapatkan dari
                                     //http://www.qtcentre.org/wiki/index.php?title=QGraphicsView:_Smooth_Panning_and_Zooming
    this->objek_QGV->scale(1.0/scaleFactor,1.0/scaleFactor);
}

void MainWindow::rotate()
{
    //kalau mau jalankan fungsi yang menembak langsung objek di dalam kelas utama,
    //maka deklarasi objek kelas yang ditembak harus dipangkas
    //lihat deklarasi QGV di atas
    //diingat kembali pada Yaum al-Ahad, Rabi` al-Thaani 22, 1435 01:13 PM dari Pemrograman Qt 5
    this->objek_QGV->rotate(45);
}

void MainWindow::reset()
{
    //kalau mau jalankan fungsi yang menembak langsung objek di dalam kelas utama,
    //maka deklarasi objek kelas yang ditembak harus dipangkas
    //lihat deklarasi QGV di atas
    //diingat kembali pada Yaum al-Ahad, Rabi` al-Thaani 22, 1435 01:13 PM dari Pemrograman Qt 5
    this->objek_QGV->resetTransform();

    //fungsi di bawah ini diambil dari kode pada kelas utama
    //gunanya untuk memaksa pucuk kiri atas gambar untuk berada di pucuk kiri atas juga dari QGV
    //ditemukan pada Yaum al-Arbi'a, Jumaada al-Awal 17, 1435 01:02 PM
    //Wednesday, March 19, 2014
    this->objek_QGS->setSceneRect(QRectF(0,0,1,1));
    this->objek_QGS->setSceneRect(0,0,pixmap->width(),pixmap->height());

}

void MainWindow::flip_horizontal()
{
/*
            QTransform gambar_berubah;

                //teknik ini didapat pada Saturday, March 29, 2014 dari https://qt-project.org/forums/viewthread/13780/
                QTransform gambar_berubah_lagi = gambar_berubah.translate(-1,1);  //khusus baris ini, ditemukan sendiri dengan coba-coba
                           //memberanikan diri memakai selain method scale()
                           //ternyata justru translate() yang mampu membolak-balikkan gambar otomatis setiap dipanggilnya fungsi,
                           //tidak seperti scale() yang mengubah gambar 1 kali saja walau dipanggil berulang kali
                           //ditemukan pada Saturday, March 29, 2014 01:00 PM
                           //namun kelemahan kode masih terjadi, sama seperti sebelum branching yakni membalik gambar hanya dari dalam bingkai pixmap BUKANNYA dari dalam QGV
                           //padahal yang diinginkan pembalikan seperti Flip pada GIMP, yakni mutlak dibalik di dalam bingkai QGV (yang terluar)
                QPixmap *pixmap_kedua = new QPixmap(pixmap->transformed(gambar_berubah_lagi));
                this->objek_QGS->addPixmap(*pixmap_kedua);*/

    //pada akhirnya solusi di atas harus dianulir dengan satu baris sederhana ini
    //Saturday, March 29, 2014 01:12 PM
    this->objek_QGV->scale(-1,1);
}

//fungsi ini baru ditambahkan pada Wednesday, April 02, 2014 01:52 PM
void MainWindow::flip_vertikal()
{
    this->objek_QGV->scale(1,-1);
}

Qt Creator dan Kode 

wavemon40

Hasil

Pan (gambar bisa di-drag)

wavemon51

Zoom In

wavemon41

Zoom Outwavemon42

Rotate (Clockwise)wavemon43

Resetwavemon44

Flip Horizontallywavemon45

Flip Verticallywavemon46

Analisis

mainwindow.h

Di header ini, tidak banyak yang harus diperhatikan. Jika Anda belum memahami penulisan header di Qt, silakan merujuk ke tulisan ini.

mainwindow.cpp

Pada berkas ini, ada banyak yang harus diperhatikan. Berikut ini saya daftarkan yang penting-penting.

  1. Pembuatan objek QGraphicsScene dan QGraphicsView.
  2. connect() antara QToolButton dengan fungsinya masing-masing.
  3. Fungsi untuk pan.
  4. Fungsi zoomin().
  5. Fungsi zoomout().
  6. Fungsi rotate().
  7. Fungsi reset().
  8. Fungsi flip_horizontal().
  9. Fungsi flip_vertikal().

Saya akan menjelaskannya satu per satu sebagai berikut.

QGraphicsScene dan QGraphicsView
                objek_QGS = new QGraphicsScene;
                objek_QGV = new QGraphicsView;  //inilah QGV yang dipangkas yang dimaksud di komentar fungsi-fungsi di bawah

Dua baris di atas adalah pembuatan objek (inisialisasi) QGraphicsScene dan QGraphicsView. Model inisialisasinya terpangkas (di bagian awalnya tidak ada nama kelas, hanya ada di bagian akhir) karena dua objek ini akan digunakan di fungsi lain di luar fungsi utama MainWindow.

objek_QGS->addPixmap(*pixmap);             //kalau suatu objek dideklarasikan dengan cara terpotong seperti baris 25 di atas
                                               //maka bentuk pemanggilan objek di dalam parameter harus diawali dengan *
                                               //ditemukan pada Yaum al-Arbi'a, Jumaada al-Awal 17, 1435 12:55 PM
                                               //Wednesday, March 19, 2014
                                               //tidak diawali dengan &, tidak diakhiri dengan & atau *

    objek_QGS->setSceneRect(QRectF(0,0,1,1));  //akhirnya setelah berjam-jam ketemu juga
                                               //sumber: http://www.qtcentre.org/threads/22372-QGraphicsScene-Scrollbar-resizing
                                               //ditemukan pada Yaum al-Khamees, Rabi` al-Thaani 19, 1435 11:06 PM / Thursday, February 20, 2014
                                               //gunanya baris ini untuk memaksa sisi kiri gambar tepat sisi kiri QGV, alias
                                               //supaya semua scrollbar selalu berada pada posisi paling awal / default
                                               //jika tidak begini, semua scrollbar selalu berada pada akhir posisinya
                                               //scrollbar nakal jika ukuran resolusi gambar melampaui ukuran QGV
    objek_QGV->setScene(objek_QGS);
    objek_QGS->setSceneRect(0,0,pixmap->width(),pixmap->height());  //get image size macam ini saya peroleh dari stackoverflow tapi lupa alamatnya
                                                                  //ini harus ada setelah QRectF di atas
    objek_QGV->setDragMode(QGraphicsView::ScrollHandDrag);

Kode di atas ini adalah persiapan untuk menayangkan gambar pada QGraphicsView (selanjutnya disebut QGV). Seperti yang telah dijelaskan kemarin, penayangan gambar di sini memerlukan persiapan QPixmap, kemudian QGraphicsScene (selanjutnya disebut QGS), baru kemudian QGV. Fungsi addPixmap untuk objek_QGS di sini diisi dengan argumen berupa objek pixmap yang berupa ponter (ada tanda *). Tentunya objek pixmap harus diisi gambar dulu sebelumnya. Jika belum mengerti cara memasukkan gambar, silakan merujuk kemari.

Ada hal penting yang harus diperhatikan mengenai posisi gambar dan scrollbar di dalam QGV. Anda harus memasang kode ini:

objek_QGS->setSceneRect(QRectF(0,0,1,1));

dan ini:

objek_QGS->setSceneRect(0,0,pixmap->width(),pixmap->height());

Kode pertama gunanya untuk memaksa semua scrollbar berada pada posisinya paling awal. Inilah kondisi normal yang tidak akan tercapat jika tidak menggunakan kode pertama. Berikut ini gambar kesalahannya:

wavemon49

Lalu jika tidak menggunakan kode kedua, maka posisi gambar yang akan meleset jauh dari posisi normal (pojok kiri atas gambar tepat pada pojok kiri atas QGV). Kode kedua adalah pengatur untuk itu. Berikut ini gambar kesalahannya:

wavemon50

Jika kedua kode dipakai dengan benar, maka hasilnya normal seperti bagian awal tulisan ini. Berikut gambarnya.

wavemon39

Kode untuk Pan

Pan itu adalah kemampuan objek untuk berpindah jika dikenai drag oleh mouse. Ini bisa dilakukan dengan memanfaatkan fungsi setDragMode() milik QGV sebagai berikut.

objek_QGV->setDragMode(QGraphicsView::ScrollHandDrag);

Perhatikan bahwa argumen QGraphicsView::ScrollHandDrag yang mengatur pan ini.

connect()

Fungsi connect() adalah bagian yang sangat penting dari Qt Framework. Fungsi ini bertugas menghubungkan antara SIGNAL dan SLOT, dua komponen vital dari Qt Framework. Dalam program ini, yang dihubungkan adalah tombol-tombol (QToolButton) ketika diklik dengan fungsi-fungsi yang sudah dipersiapkan sebelumnya. Fungsi connect() selalu ada setiap ada hubungan SIGNAL dan SLOT. Sedangkan SIGNAL dan SLOT ada setiap kita menginginkan event tertentu berlaku jika ada suatu klik/pemicu lain. SIGNAL dan SLOT di Qt Framework itu mudah dipahami. Berikut ini kodenya.

    connect(tombol_zoomin,   SIGNAL(clicked()),  this,  SLOT(zoomin()));
    connect(tombol_zoomout,  SIGNAL(clicked()),  this,  SLOT(zoomout()));
    connect(tombol_reset,    SIGNAL(clicked()),  this,  SLOT(reset()));
    connect(tombol_rotate,   SIGNAL(clicked()),  this,  SLOT(rotate()));
    connect(tombol_flip_horizontal,     SIGNAL(clicked()),  this,  SLOT(flip_horizontal()));
    connect(tombol_flip_vertikal,     SIGNAL(clicked()),  this,  SLOT(flip_vertikal()));
Fungsi-Fungsi

Bagian paling menarik dari program ini untuk dibahas adalah fungsi-fungsinya. Ada 6 fungsi. Saya akan bahas sebagai berikut.

1. Zoom In
void MainWindow::zoomin()
{
    double scaleFactor = 1.25;
    //kalau mau jalankan fungsi yang menembak langsung objek di dalam kelas utama,
    //maka deklarasi objek kelas yang ditembak harus dipangkas
    //lihat deklarasi QGV di atas
    //diingat kembali pada Yaum al-Ahad, Rabi` al-Thaani 22, 1435 01:13 PM dari Pemrograman Qt 5
//    this->objek_QGV->scale(scaleFactor,scaleFactor);
//    QTransform flip;
    this->objek_QGV->scale(scaleFactor, scaleFactor);

}

Perlu diperhatikan bahwa seluruh transformasi di dalam program ini dilakukan oleh fungsi-fungsi milik QGV itu sendiri. Untuk melakukan zoom in (perbesar ke dalam), kita cukup memanggil fungsi scale() dengan 2 argumennya yakni x dan y. Di sini saya memakai variabel bertipe double dengan ukuran 1.25. Tujuannya supaya sama besar antara perbesaran positif (zoom in) dan perbesaran negatif (zoom out) sebagaimana ditemukan di program pengolah gambar.

2. Zoom Out
void MainWindow::zoomout()
{
    //kalau mau jalankan fungsi yang menembak langsung objek di dalam kelas utama,
    //maka deklarasi objek kelas yang ditembak harus dipangkas
    //lihat deklarasi QGV di atas
    //diingat kembali pada Yaum al-Ahad, Rabi` al-Thaani 22, 1435 01:13 PM dari Pemrograman Qt 5

    double      scaleFactor = 1.25;  //istimewa pada Yaum al-Ahad, Rabi` al-Thaani 22, 1435 01:33 PM
                                     //didapatkan dari
                                     //http://www.qtcentre.org/wiki/index.php?title=QGraphicsView:_Smooth_Panning_and_Zooming
    this->objek_QGV->scale(1.0/scaleFactor,1.0/scaleFactor);
}

Zoom out adalah kebalikan zoom in. Jika di zoom in kita pakai argumen scaleFactor begitu saja (alias 1.0*scaleFactor), maka di zoom out ini kita balik menjadi 1.0/scaleFactor agar gambarnya mengecil. Dengan zoom out, kita tahu bahwa perlu adanya suatu nilai pasti yang menjadi satuan baku perbesaran. Bahasa kasarnya, Anda klik ZOOM IN 2 kali maka gambar membesar, klik ZOOM OUT 2 kali juga maka gambar kembali seperti semula.

3. Rotate
void MainWindow::rotate()
{
    //kalau mau jalankan fungsi yang menembak langsung objek di dalam kelas utama,
    //maka deklarasi objek kelas yang ditembak harus dipangkas
    //lihat deklarasi QGV di atas
    //diingat kembali pada Yaum al-Ahad, Rabi` al-Thaani 22, 1435 01:13 PM dari Pemrograman Qt 5
    this->objek_QGV->rotate(45);
}

Perputaran di sini saya atur 45 derajat searah jarum jam (positif). Ini sama juga dengan sebelumnya, hanya menggunakan fungsi bawaan QGV.

4. Reset
void MainWindow::reset()
{
    //kalau mau jalankan fungsi yang menembak langsung objek di dalam kelas utama,
    //maka deklarasi objek kelas yang ditembak harus dipangkas
    //lihat deklarasi QGV di atas
    //diingat kembali pada Yaum al-Ahad, Rabi` al-Thaani 22, 1435 01:13 PM dari Pemrograman Qt 5
    this->objek_QGV->resetTransform();

    //fungsi di bawah ini diambil dari kode pada kelas utama
    //gunanya untuk memaksa pucuk kiri atas gambar untuk berada di pucuk kiri atas juga dari QGV
    //ditemukan pada Yaum al-Arbi'a, Jumaada al-Awal 17, 1435 01:02 PM
    //Wednesday, March 19, 2014
    this->objek_QGS->setSceneRect(QRectF(0,0,1,1));
    this->objek_QGS->setSceneRect(0,0,pixmap->width(),pixmap->height());

}

Fungsi reset ini maksudnya mengembalikan gambar seperti semula setelah banyak diubah ini dan itu. Sederhana saja, cukup memanggil fungsi resetTransform milik QGV. Lalu memanggil ulang rekonstruksi QGS (yang dua baris itu).

5. Flip Horizontally
void MainWindow::flip_horizontal()
{
/*
            QTransform gambar_berubah;

                //teknik ini didapat pada Saturday, March 29, 2014 dari https://qt-project.org/forums/viewthread/13780/
                QTransform gambar_berubah_lagi = gambar_berubah.translate(-1,1);  //khusus baris ini, ditemukan sendiri dengan coba-coba
                           //memberanikan diri memakai selain method scale()
                           //ternyata justru translate() yang mampu membolak-balikkan gambar otomatis setiap dipanggilnya fungsi,
                           //tidak seperti scale() yang mengubah gambar 1 kali saja walau dipanggil berulang kali
                           //ditemukan pada Saturday, March 29, 2014 01:00 PM
                           //namun kelemahan kode masih terjadi, sama seperti sebelum branching yakni membalik gambar hanya dari dalam bingkai pixmap BUKANNYA dari dalam QGV
                           //padahal yang diinginkan pembalikan seperti Flip pada GIMP, yakni mutlak dibalik di dalam bingkai QGV (yang terluar)
                QPixmap *pixmap_kedua = new QPixmap(pixmap->transformed(gambar_berubah_lagi));
                this->objek_QGS->addPixmap(*pixmap_kedua);*/

    //pada akhirnya solusi di atas harus dianulir dengan satu baris sederhana ini
    //Saturday, March 29, 2014 01:12 PM
    this->objek_QGV->scale(-1,1);
}

Pembalikan gambar (translasi/mirror) ini sebenarnya memusingkan untuk saya yang tidak tahu soal QGV. Setelah melakukan pencarian, berpusing ria, tambal sulam kode, saya akhirnya menggunakan kembali fungsi scale() milik QGV. Hanya saja, di sini nilai argumennya -1 dan 1. Ini akan membuat yang kanan menjadi yang kiri pada gambar.

Kelemahan: jika sebelumnya gambar sudah di-rotate, maka yang dibalik adalah gambar di dalam bingkai pixmap saja, tidak dibalik secara mutlak. Ini akan berbeda dengan aplikasi pengolah gambar biasanya. Saya belum menemukan solusinya.

6. Flip Vertically
void MainWindow::flip_vertikal()
{
    this->objek_QGV->scale(1,-1);
}

Sama dengan yang horizontal, hanya memakai fungsi scale() tetapi dengan nilai argumen 1 dan -1. Ini akan membuat yang atas menjadi yang bawah. Kelemahannya juga sama dengan yang horizontal.

Kesimpulan

  1. Penayangan gambar di Qt Framework bisa dilakukan dengan QPixmap, QGraphicsScene, dan QGraphicsView.
  2. Manipulasi gambar sederhana dengan QGV cukup dilakukan dengan method-method milik QGV itu sendiri.

Unduh Kode Sumber

Program kali ini bernama WajahDepan. Silakan unduh kode sumber berikut dan bukalah di Qt Creator Anda. Semoga bermanfaat.

Penutup

Walau sudah puas sekali, saya masih menyisakan satu misteri mengenai flip pada QGV. Semoga tulisan ini bermanfaat

Referensi

5 thoughts on “Pemrograman Qt 17 – Pan, Scroll, Zoom, Flip, dan Rotate untuk QGraphicsView

Dilarang menggunakan emotikon

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s