Pemrograman Qt 17 – Pan, Scroll, Zoom, Flip, dan Rotate untuk QGraphicsView Bismillahirrahmanirrahim. Tulisan 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 1. 2. 3. 4. 5. 6.
QGraphicsScene QGraphicsView QToolButton QVBoxLayout QHBoxLayout QWidget
Daftar Method 1. setSceneRect() -> milik QGraphicsScene 2. addPixmap() -> milik QGraphicsScene 3. setScene() -> milik QGraphicsView 4. setDragMode() -> milik QGraphicsView 5. scale() -> milik QGraphicsView 6. rotate() -> milik QGraphicsView 7. resetTransform() -> milik QGraphicsView 8. zoomin() -> buatan sendiri 9. zoomout() -> buatan sendiri 10. reset() -> buatan sendiri 11. rotate() -> buatan sendiri 12. flip() -> buatan sendiri
Arah Tulisan Ini
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 QGraphicsView
*objek_QGS; *objek_QGV;
QVBoxLayout QHBoxLayout QVBoxLayout QVBoxLayout
*layout_utama; *layout_isi_global; *layout_kiri_gambar; *layout_kanan_tombol;
QWidget QWidget QWidget QPixmap
*fondasi; *panel_kiri; *panel_kanan; *pixmap;
double
public slots: void void void void void void private:
scaleFactor; zoomin(); zoomout(); flip_horizontal(); flip_vertikal(); rotate(); reset();
};
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 QToolButton QToolButton QToolButton QToolButton QToolButton
*tombol_zoomin *tombol_zoomout *tombol_rotate *tombol_reset *tombol_flip_horizontal *tombol_flip_vertikal
= = = = = =
new new new new new new
QToolButton; QToolButton; QToolButton; QToolButton; QToolButton; 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 normal QWidget QWidget
*fondasi
= new QWidget;
//deklarasi objek di CPP harus
*panel_kanan *panel_kiri
= new QWidget; = new QWidget;
//sama sekali tidak boleh diringkas //atau, segmentation fault
pixmap = new QPixmap(":/gambar/ubuntu"); supaya bisa dipakai di fungsi luar buatan sendiri pixmap dipanggil di suatu fungsi sebagai dipanggil dengan didahului *
//deklarasi terpotong //dan nanti kalau objek //parameter, maka
//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); //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);
//sisi kiri
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); layout_utama->addWidget(panel_kanan);
//widget panel kiri //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)); juga
//akhirnya setelah berjam-jam ketemu
//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; 22, 1435 01:33 PM
//istimewa pada Yaum al-Ahad, Rabi` al-Thaani
//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://qtproject.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 membolakbalikkan 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
Hasil Pan (gambar bisa di-drag)
Zoom In
Zoom Out
Rotate (Clockwise)
Reset
Flip Horizontally
Flip Vertically
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. 2. 3. 4. 5. 6. 7. 8. 9.
Pembuatan objek QGraphicsScene dan QGraphicsView. connect() antara QToolButton dengan fungsinya masing-masing. Fungsi untuk pan. Fungsi zoomin(). Fungsi zoomout(). Fungsi rotate(). Fungsi reset(). Fungsi flip_horizontal(). 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)); juga
//akhirnya setelah berjam-jam ketemu
//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:
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:
Jika kedua kode dipakai dengan benar, maka hasilnya normal seperti bagian awal tulisan ini. Berikut gambarnya.
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 fungsifungsi 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; 22, 1435 01:33 PM
//istimewa pada Yaum al-Ahad, Rabi` al-Thaani
//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://qtproject.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 membolakbalikkan 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. Alamat: http://otodidak.freeserver.me/tarball/WajahDestop.tar.gz Ukuran: 500 KB
Penutup Walau sudah puas sekali, saya masih menyisakan satu misteri mengenai flip pada QGV. Semoga tulisan ini bermanfaat
Referensi • •
http://www.qtcentre.org/wiki/index.php? title=QGraphicsView:_Smooth_Panning_and_Zooming https://qt-project.org/forums/viewthread/13780/
12. Tentang Dokumen Ini Dokumen ini adalah versi PDF dari posting asli http://malsasa.wordpress.com/2014/04/04/pemrograman-qt-17-pan-scroll-zoom-flip-danrotate-untuk-qgraphicsview/. Dokumen ini ditulis dengan fonta Ubuntu 12pt. Dokumen ini disusun ulang dengan Libreoffice Writer 3.5. Dokumen ini selesai disusun pada 4 Maret 2014. Penulis mohon maaf jika terdapat kesalahan dalam dokumen ini.
13. Tentang Penulis Penulis adalah warga Forum Ubuntu Indonesia. Penulis mendukung pendidikan perangkat lunak legal (terutama FOSS) untuk masyarakat. Penulis menyediakan buku-buku panduan Linux untuk pemula maupun ahli untuk diunduh secara gratis 1. Penulis bisa dihubungi via SMS di nomor 0896 7923 7257.
1
http://malsasa.wordpress.com/pdf