Pemrograman Qt 19 Membaca dan Menuliskan Standard Output ke QTextEdit Secara Realtime Bismillahirrahmanirrahim. Setelah tulisan pemrograman Qt 10 kemarin, saya berpikir untuk memperbaiki program ProyekRC dengan menambah fungsi penayangan standard output untuk apt-get. Standard output yang ditayangkan harus real time (bergerak terus sampai proses selesai). Di dalam suatu program repo changer, tentu fitur ini wajib ada. Jika tidak, maka pengguna harus membuka 1 program lagi (Terminal) untuk sekadar melakukan apt-get update. Setelah melakukan riset kecil-kecilan, pada tulisan ini saya berhasil melakukannya secara terpisah. Anda dapat mengunduh kode sumber pada akhir tulisan. Semoga tulisan ini bermanfaat. 1. Spesifikasi Sistem Ubuntu 12.04 Qt Creator 2.4.1 Qt 4.8 2. Daftar Kelas 1. QProcess 2. QStringList 3. QTextCursor 4. QTextEdit 5. QWidget 6. QVBoxLayout 7. QPushButton 3. Daftar Method 1. setrange() <- milik QIntValidator 2. setvalidator() <- milik QLineEdit 3. setechomode() <- milik QLineEdit 4. setfilename() <- milik QFile 5. open() <- milik QFile 6. operator <<() <- milik QTextStream 4. Arah Tulisan Ini
Program harus mampu membaca standard output dari apt-get update ketika bekerja sampai selesai. Standard ouput tersebut harus ditayangkan di QTextEdit. Diharapkan hasilnya nanti seperti Synaptic ketika bekerja. Lihat gambar berikut. Mengapa ini harus dibuat? Karena program RepoChanger pada tulisan ke-10 harus memiliki fitur penting ini.
5. Kode mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include namespace Ui class MainWindow; class MainWindow : public QMainWindow Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); QPushButton *tomboloke; QWidget *widgetutama; QVBoxLayout *layoututama; QTextEdit *keluarankonsol; public slots: void redirect_output(); void hapus_isi_teks(); void tunjukkan_bahwa_kamu_mati(); private slots: void ambillah_datanya(); private: Ui::MainWindow *ui; QProcess *prosesku; ; #endif // MAINWINDOW_H
mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) this->setgeometry(333, 333, 355, 355); QPushButton *tomboloke = new QPushButton; QVBoxLayout *layoututama = new QVBoxLayout; QWidget *widgetutama = new QWidget; keluarankonsol = new QTextEdit; prosesku = new QProcess; tomboloke->settext("nothing TO SAY"); // keluarankonsol->settextbackgroundcolor("red"); layoututama->addwidget(tomboloke); layoututama->addwidget(keluarankonsol); prosesku->setprocesschannelmode(qprocess::mergedchannels); //menghitamkan background dari QTextEdit dengan CSS keluarankonsol->setstylesheet("qtextedit background-color : black; color : white; "); //membuat scrollbar selalu otomatis mengikuti kursor terbawah //dipasang pada Wednesday, March 26, 2014 05:39 PM dari dokumentasi Qt keluarankonsol->ensurecursorvisible(); widgetutama->setlayout(layoututama); this->setcentralwidget(widgetutama); connect(tomboloke, SIGNAL(clicked()), this, SLOT(redirect_output())); //teknik S&S baru ini didapatkan pada Tuesday, March 25, 2014 dari http://minhazulhaque.blogspot.com/2012/07/read-shell-command-output-using.html //juga bisa didapatkan dari http://www.qtcentre.org/threads/47538-qprocessread-from-stdout-lively connect(prosesku, SIGNAL(readyRead()), this, SLOT(ambillah_datanya())); //teknik pembacaan kematian proses ini ditemukan pada Wednesday, March 26, 2014 05:18 PM dari perkiraan dan dokumentasi Qt connect(prosesku, SIGNAL(finished(int)), this, SLOT(tunjukkan_bahwa_kamu_mati())); // connect(prosesku, SIGNAL(readyReadStandardError()), this, SLOT(ambillah_datanya())); //satu MainWindow::~MainWindow() delete ui;
//dua void MainWindow::hapus_isi_teks() //tiga void MainWindow::redirect_output() prosesku->start("sh", QStringList() << "-c" << "apt-get update"); //empat void MainWindow::ambillah_datanya() //teknik appending ini ditemukan pada Tuesday, March 25, 2014 05:07 PM dari http://www.jcjc-dev.com/2013/03/qt-48- appending-text-to-qtextedit.html this->keluarankonsol- >movecursor(qtextcursor::end); this->keluarankonsol->insertplaintext(prosesku->readall()); this->keluarankonsol->movecursor(qtextcursor::end); // this->keluarankonsol->setplaintext(prosesku->readallstandarderror()); void MainWindow::tunjukkan_bahwa_kamu_mati() this->keluarankonsol->insertplaintext("\n\n===proses SELESAI===\n\n");
6. Qt Creator dan Kode
7. Hasil
8. Analisis Saya berusaha memberikan analisis dimulai dari yang paling penting. 8.1 Penayangan Standard Output pada QTextEdit Inilah inti program. Ini dilakukan hanya dengan objek QTextEdit dengan beberapa method. Berikut ini kodenya. //empat void MainWindow::ambillah_datanya() //teknik appending ini ditemukan pada Tuesday, March 25, 2014 05:07 PM dari http://www.jcjc-dev.com/2013/03/qt-48-appending-text-to-qtextedit.html this->keluarankonsol->movecursor(qtextcursor::end); this->keluarankonsol->insertplaintext(prosesku->readall()); this->keluarankonsol->movecursor(qtextcursor::end); Pada intinya, program ini hanya melakukan 3 aksi. Pertama, dia meletakkan kursor pada akhir baris. Kedua, dia membaca standard output (dan standard error juga). Ketiga, dia meletakkan kembali kursor pada akhir baris. Inilah yang membuat program dapat membaca standard output secara realtime. Namun fungsi ambillah_datanya() ini tidak akan mampu membaca jika tidak ada SIGNAL dan SLOT berikut. connect(prosesku, SIGNAL(readyRead()), this, SLOT(ambillah_datanya())); SIGNAL readyread() dari objek prosesku (QProcess) inilah yang membuat SLOT ambillah_datanya() senantiasa dijalankan untuk membaca standard output. Tanpa ini, program ini tidak realtime. 8.2 Eksekusi Perintah apt-get update dari Program //tiga void MainWindow::redirect_output() prosesku->start("sh", QStringList() << "-c" << "apt-get update"); // prosesku->start("sh", QStringList() << "-c" << "tailf /var/log/syslog"); Seperti yang kita lakukan pada pemrograman Qt 9, kita memanfaatkan QProcess untuk menjalankan perintah shell di sini. Perhatikan standar penulisan perintah pada baris yang aktif dan yang dijadikan komentar di atas.
8.3 Pemeriksaan Status Berakhirnya Proses apt-get update void MainWindow::tunjukkan_bahwa_kamu_mati() this->keluarankonsol->insertplaintext("\n\n===proses SELESAI===\n\n"); Ide dasarnya adalah perilaku Synaptic setiap proses instalasi selesai. Dia selalu bisa menayangkan pesan bahwa proses instalasi sudah selesai dan Anda bisa menutup jendelanya. Bagaimana Synaptic tahu bahwa proses bekerja apt sudah berakhir? Qt bisa melakukannya dengan SIGNAL dan SLOT, dengan SIGNAL berisi argumen finished(int) untuk QProcess yang menjalankan apt-get. Artinya, jika QProcess mengeluarkan sinyal finished, maka segera panggil SLOT tunjukkan_bahwa_kamu_mati() di atas. Baris kode di atas akan dikerjakan setelah adanya baris SIGNAL dan SLOT berikut. connect(prosesku, SIGNAL(finished(int)), this, SLOT(tunjukkan_bahwa_kamu_mati())); 8.4. Membuat Standard Output dan Standard Error Dikeluarkan Bersamaan prosesku->setprocesschannelmode(qprocess::mergedchannels); Seperti yang Anda ketahui, apt tidak hanya mengeluarkan pesan output biasa. Ia juga mengeluarkan pesan error jika terjadi error. Pesan error itu dikeluarkan pada kanal yang berlainan dengan output biasa. Nama kanalnya standard output. Sedangkan nantinya aplikasi ini akan dipakai oleh pengguna pemula, sehingga pesan error sangat dibutuhkan. Oleh karena itu, pesan error harus juga bisa ditayangkan sebagaimana pesan output normal. Ini dilakukan dengan menggabungkan kanal standard output dan standard error jadi satu. Method-nya adalah setprocesschannelmode() dengan argumen QProcess::MergedChannels. Ini membuat program menayangkan standard output jika memang dalam keadaan normal dan menayangkan standard error jika memang ada error. 8.5. Lain-Lain 8.5.1 Scrollbar Selalu Menggulung Ke Bawah Mengikuti Kursor keluarankonsol->ensurecursorvisible(); Mungkin ini remeh. Tetapi ini penting untuk memudahkan pengguna. Method ensurecursorvisible() memastikan bahwa scrollbar akan selalu menggulung ke bawah mengikuti arah kursor bergerak. Seperti halnya Synaptic ketika instalasi. 8.5.2 Pembuatan GUI Jika Anda belum memahami pemrograman GUI secara hard coding di Qt, Anda bisa merujuk
ke tulisan sebelumnya. Anda bisa mulai dari memahami pembuatan GUI-nya di pemrograman Qt 1 kemudian memahami penulisan header di pemrograman Qt 5. 9. Kesimpulan 1. Pembacaan standard output (dan standard error) secara realtime bisa dilakukan dengan menghubungkan SIGNAL readyread() dan SLOT method readall() pada objek QProcess. 2. Untuk membuat setiap baris standard output dicetak sebagai satu baris pula di QTextEdit, harus digunakan method movecursor() dengan argumen QTextCursor::End pada QTextEdit. 3. Untuk membuat scrollbar bergerak terus ke bawah mengikuti kursor secara realtime, harus digunakan method ensurecursorvisible() pada QTextEdit. 4. Untuk menggabungkan kanal standard output dan standard error, harus digunakan method setprocesschannelmode() dengan argumen QProcess::MergedChannel pada QProcess. 5. Untuk memeriksa masih bekerja atau sudah berhentinya suatu proses, harus digunakan SIGNAL finished(int) pada QProcess dengan SLOT-nya fungsi untuk menulis pesan berakhirnya proses. 10. Unduh Kode Sumber Program kali ini bernama Konsolidasi. Silakan unduh dan buka di Qt Creator Anda. Alamat: http://otodidak.freeserver.me/tarball/konsolidasi.tar.gz Ukuran: 30 KB 11. Referensi 1. http://minhazulhaque.blogspot.com/2012/07/read-shell-command-outputusing.html 2. http://www.qtcentre.org/threads/47538-qprocess-read-from-stdout-lively 3. http://www.jcjc-dev.com/2013/03/qt-48-appending-text-to-qtextedit.html 12. Tentang Dokumen Ini Dokumen ini adalah versi PDF dari posting asli http://malsasa.wordpress.com/2014/04/26/pemrograman-qt-19-membaca-dan-menuliskanstandard-output-ke-qtextedit-secara-realtime/. Dokumen ini ditulis dengan fonta Ubuntu 12pt. Dokumen ini disusun ulang dengan Libreoffice Writer 3.5. Dokumen ini selesai disusun pada 2 Mei 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