Membuat Aplikasi Bisnis

Menggunakan bahasa Python dan database berbasis SQL

Oleh: Owo Sugiana <sugiana@rab.co.id> JAKARTA 29 September 2002 - 7 Februari 2003

2

Daftar Isi
I Pendahuluan
1 Pemrograman Komputer
1.1 1.2 1.3 Mengapa Kita Butuh Program Bahasa Pemrograman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15
17
17 18 18

Siklus Pengembangan Program

2 Bahasa Pemrograman
2.1 2.2 2.3 2.4 Mengapa Python . . . . . . . . . . . . . . . . . . Nama Python . . . . . . . . . . . . . . . . . . . . Pemrograman Terstruktur . . . . . . . . . . . . . Dokumentasi . . . . . . . . . . . . . . . . . . . .

21
21 23 23 24

3 Teknik Penulisan
3.1 3.2 Gaya . . . . . . . . . . . . . . . . . . . . . . . . . Jenis Huruf dan Simbol 3 . . . . . . . . . . . . . .

27
27 27

4

DAFTAR ISI
29
. . . . . . . . . . . . . . . . . . . 29 29 4.1 4.2 Paket Program

4 Persiapan
Text Editor . . . . . . . . . . . . . . . . . . . . .

II Python
5 Hello World
5.1 Aturan Penulisan . . . . . . . . . . . . . . . . . . 5.1.1 5.1.2 5.1.3 5.2 5.3 Indent . . . . . . . . . . . . . . . . . . . . Baris Perintah . . . . . . . . . . . . . . . Keterangan Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

31
33
33 34 34 35 35 35

Variabel . . . . . . . . . . . . . . . . . . . . . . . Modus Interaktif

6 Tipe Data
6.1 Bilangan . . . . . . . . . . . . . . . . . . . . . . . 6.1.1 6.1.2 6.1.3 6.1.4 6.2 String 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 List 6.3.1 Operator . . . . . . . . . . . . . . . . . . Pengelompokan Operasi . . . . . . . . . . Pembulatan . . . . . . . . . . . . . . . . . Bentuk Tampilan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Penjumlahan & Perkalian . . . . . . . . . String Format . . . . . . . . . . . . . . . . String Menjadi Integer String Menjadi Float Panjang String Penambahan -

37
37 38 38 40 40 41 42 42 43 43 43 43 44

len()

int() float()

. . . . . . . . . . . .

. . . . . . . . . . &

. . . . . . . . . . . . . . . . . . . . . . . . .

append()

insert()

. .

DAFTAR ISI
6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.3.8 6.3.9 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.5 6.6 Penghapusan Pemenggalan Panjang List -

5

del

. . . . . . . . . . . . .

44 45 45 45 45 47 47 48 48 49 49 49 49 50 50

String Sebagai List . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

len()

. . . . . . . . . . . .

List Dalam List . . . . . . . . . . . . . . . Membalikkan Urutan Mengurutkan Menyalin -

sort() list() . .

reverse()

. . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Dictionary - Key & Value Daftar Kunci Daftar Nilai Menghapus -

keys() . values()

. . . . . . . . . . . . .

Menambah Atau Mengubah Nilai -

del

update()

Mengetahui Tipe Data -

Daftar Fungsi Suatu Objek -

type() . dir()

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7 Kondisi
7.1 7.2 7.3 7.4 7.5 Bentuk Logika Selain Itu Selain Itu

51
else . . . Jika - elif not
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 53 53 54 55 55 55 56

Operator Perbandingan Operator Logika 7.5.1 7.5.2 7.5.3 Bukan -

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Semua Kondisi Terpenuhi -

and

Salah Satu Kondisi Terpenuhi -

or

. . . . . . . . . .

8 Perulangan - Loop
8.1 8.2 Jumlah Perulangan Ditetapkan Selama -

while

for

59
. . . . . . . 59 60

. . . . . . . . . . . . . . . . . . .

6

DAFTAR ISI
8.3 Keluar Dari Perulangan -

break

. . . . . . . . .

62

9 Fungsi
9.1 9.2 9.3 9.4 9.5 Nilai Masukan . . . . . . . . . . . . . . . . . . . . Nilai Keluaran -

63
64 64 65 65 66

return

. . . . . . . . . . . . . .

Memanggil Dirinya . . . . . . . . . . . . . . . . . Kepemilikan Variabel . . . . . . . . . . . . . . .

Fungsi Interpreter - exec() . . . . . . . . . . . . .

10 File
10.1 Baca Tulis . . . . . . . . . . . . . . . . . . . . . . 10.2 Printer . . . . . . . . . . . . . . . . . . . . . . . . 10.2.1 Ukuran Huruf . . . . . . . . . . . . . . . . 10.2.2 Ganti Halaman . . . . . . . . . . . . . . . 10.2.3 Mencetak File . . . . . . . . . . . . . . . . 10.3 Direktori Aktif . . . . . . . . . . . . . . . . . . .

69
69 70 70 70 71 72

11 Menangani Kesalahan - Exception 12 Proyek String
12.1 Membuat Nomor Baris . . . . . . . . . . . . . . 12.1.1 Awali Dengan Nol 12.1.2 Penunjuk Pada 12.2 File Sebagai Tabel

73 75
75 76 76 76 78 78 78 78

zfill() File - seek()

. . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

12.2.1 Membelah String 12.2.2 12.2.3 12.2.4

splitfields() . . . . Hapus Karakter Tak Tampak - strip() . Rata Kiri dan Kanan - ljust() & rjust() Kunci Pada Dictionary - has_key() . . .

DAFTAR ISI

7

III Qt
13 Pendahuluan 14 Aplikasi Pertama
14.1 Berorientasi Objek . . . . . . . . . . . . . . . . . 14.2 Program Utama 14.3

79
81 83
84 84 85 85 . . . . . . . . . . . . . . . . . .

self

. . . . . . . . . . . . . . . . . . . . . . . . .

14.4 Fungsi Pada Objek . . . . . . . . . . . . . . . . .

15 Visual Class
15.1 Buku Alamat . . . . . . . . . . . . . . . . . . . . 15.1.1 Parent dan Child . . . . . . . . . . . . . . 15.1.2 Parent dan Owner 15.1.4 Modul 15.2 Sinyal . . . . . . . . . . . . . 15.1.3 Dengan Atau Tanpa

87
87 89 89 90 90 90 91 93 94 95 96 96 98 99 99 101 105 106

qt

self

. . . . . . . . .

. . . . . . . . . . . . . . . . . .

15.1.5 String Atau QString . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.2.1 Keterkaitan Dengan C++ . . . . . . . . . 15.2.2 Sinyal atau Event 15.2.3 Membuat Event 15.3.1 Font -

15.3 Hiasan . . . . . . . . . . . . . . . . . . . . . . . . 15.3.2 Warna -

QFont . . QColor

15.3.3 Parent Berpengaruh 15.4 Ya Atau Tidak 15.5 15.6

QCheckBox . . . Pilih Salah Satu - QRadioButton Daftar Fluktuatif - QComboBox .

15.7 Listbox

. . . . . . . . . . . . . . . . . . . . . . .

. . . . .1 Widget . . 18. . . . . . . . . .8 DAFTAR ISI 15. . . . . . . . .2 Pesan & Konrmasi 145 146 149 . . .3 Layout Dengan Metode Grid 131 131 133 136 19 Waktu 19.10. . . .1 File Dialog . . . .Enable .4 Timer 139 139 140 142 143 QDate . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Kasir I 17 Wadah . . . . . . .Container 17. . . . . . . . . . . . . . . 17. . . . .3 Tanggal dan Jam . . . . . . . . .10Hanya Keyboard 110 111 113 113 114 117 15. . . . . . . . . . . . . . . . 15. 19. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Form Dialog 20. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 Multigroup 119 123 123 123 123 127 18 Penataan 18. . . . . . . . . . .3 NumLock . . . . . . .8 Widget Aktif . . .2 Panel . . . . . . . 17. . . . . . . . . . . . 17. .1 Fleksibilitas Ukuran 18. . . . . . . . . . .2 Tombol Keyboard 15. . . . . . . . . . .9 LCD . . . . . . . . . . . . . . . . . . . .1 Tanpa Mouse . . . 15. . . . . . . . . . . . .3 Groupbox . . . . . . . . . . . . . . . . . . . . . 20. . 15. . . .2 Tanggal 19. . . . . . . . . . . . . .10. . . . .2 Fleksibilitas Posisi . . . . . . . . . . 19. . .1 Jam . . . . . . . . . . . . . . . . . . . . .10. . . . . . . . . . . .

. . 155 157 161 168 22 Kasir II 23 Database 23. . . . . . . . . . . 175 179 180 180 181 181 185 185 189 190 191 192 193 196 197 198 210 213 23. . . . . . .1. . .3 Membuat Tabel . . . . . . . . .5. . . . . . . . . . . . .1 Membuat Database . . . . .4 Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 Struktur Tabel . . . . . . . . . .1 Current Record . . . .5. . .4 NULL . . . .1 Mengubah Sifat . . .3 Pengganti Perintah SQL . . . . . . . . . 23. . . . . .4. . . . . . . . . . . . . . . . 23. . . . . . . . . . . . . . . . . . . .5 Cara Lain Menangani Tabel 23. . . . . . . . . . . . 9 152 21 Tabel 21. . 21. .1 PostgreSQL . . . . .DAFTAR ISI 20. . . . . . . . . . .4. . . . . . . . .2 Form Login 23. . . . .5. . . . . . . . . . 23. . . . . .5. . . .2 Bentuk Tampilan . . . . . . . . . . . . . . . . . . 23.5. .7 Nomor Urut . .5 Pengisian Data yang Lebih Nyaman 23. . . . 217 217 . . . . . 23. . . . . . . . . . . . 23. . . . . . . . .5. . . . . . 21. . . . .2 Bentuk Tampilan . . . . . . . . . . . . . . . .2 Variant 23. .1. . . . .5. . 24 Kasir III 24. . . . . . . .Sort 23. . . . . . . . . . . . . . . . . . . . .6 Urutkan . . . . . . . . . .3 Form Pencarian . .1 Browsing 23. . . . . . . . . . .Autoincrement . . 23. . . . . . .2 MySQL 23. . . . . . .3 Input . . . .

24. . . . . . . . . . .5 Program . . . . . . 24. . . .6 Laporan . . . . . . . . . . .4 Jam Sibuk . . . .6. . .6. . . . . 24.6. . . . . . . .4 Pencetakan . . . . . . . . . . .2 Total Penjualan Harian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 Penyimpanan Data .1 Barang Terlaris .6. 24. . . . . . . . . . . . . . . . . . . . . . . . . 24. . . . . . 218 219 219 219 225 225 226 226 226 24.2 Daftar Barang 24. . . . . . . . .3 Rata-rata Penjualan Harian . . . . . . . . . . . . . . . . . . . . . . . 24. . . .10 DAFTAR ISI 24. .

. . . . .1 6. . .2 Operator Bilangan . . . . . . . .Daftar Tabel 6. . . . . . . . Operator Perbandingan Operator Logika . . . . . . . . . . 11 . . . . . . . . . . . . . . . . 39 46 54 57 Contoh pemenggalan list . .2 7. . .1 7. . . . . . . . . . . . .

12 DAFTAR TABEL .

. . . . . . . . . . . .3 Radiobutton . . . . . . . . . . . . . . . . . . . . . . . . . . 15. . . . . . . .1 6.Daftar Gambar 1. . . . . . . . . .6 Disable Widget . . . . . . . . . . . . . . . . . . .4 Combobox . . . . . . . . . . 15. . . . . . . . . . . . . . . . . . . .1 File Dialog . .5 Listbox . . . . . . . . . . . . . . . 15. . . . .7 LCD . . . . . . . . . . . . 15. . . . . . . 15. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15. . . . . . . . . . . . .2 Text Editor . . . . . . . . 45 84 89 100 103 105 107 110 112 114 147 149 14. . . . .8 Tombol pintas (shortcut-key) 20. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 Hello World ! 15.1 Siklus Pengembangan Program (development cycle) 19 Nomor index pada list .2 Checkbox . .1 Form Alamat 15. 13 . 20. .

. . . . . . .5 DBGrid . . . . . . . . . . . . . . . . 24. . . . . . . . .4 CursorTable 23. . . . .2 ValueGrid . . 155 161 181 194 195 199 218 23. . . . . . .1 QTable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 QDataTable . . . . . . . . . . . . . . . . . . . .1 Form Login 23. .1 Kasir . . . . . . . . . . . . . . . . . . . . . . . 21. . . . . . . . . . . . 23. . . . . .14 DAFTAR GAMBAR 21. . . . . . . . . . . . . . . . . . .

Secara teknis platform yang digunakan dalam contoh pro15 . Berbagai paket pemrograman . Oleh karena itu dibutuhkan banyak tulisan .juga semakin memudahkan para programmer dalam membuatnya. kemudian ulasan teknis pemrograman dibahas serinci mungkin. Pembahasannya diupayakan melalui konsep terlebih dahulu. Praktis kini pertumbuhan pengembang perangkat lunak ( software developer ) kian mengalami percepatan. Banyaknya contoh program diharapkan semakin memudahkan pemahaman. Kehadiran buku ini bermaksud untuk menumbuhkan minat bagi calon programmer atau sebagai referensi bagi para programmer lainnya agar dukungan lokal ( local support ) semakin tercapai terhadap perangkat lunak yang digunakan masyarakat.baik dari dalam maupun luar negeri .Kata Pengantar Pengembangan aplikasi bisnis di Indonesia sudah sangat berkembang dan memiliki potensi pasar yang masih sangat luas. Jadi selain membaca ulasan juga perhatikan alur programmnya.yang dapat memenuhi kebutuhan para pengembang.baik bersifat referensi maupun tutorial .

dan Henry (Bina Nusantara).16 DAFTAR GAMBAR gram adalah berbasis Linux. Seluruh kebutuhan dalam menjalankan contoh program sudah tersedia dalam CD tersebut. modus teks ( library ) standar yang dibawa dalam satu paket Bagian ini mengulas hal-hal yang dijalankan pada console ). Mahendra Putra. Bagian keduanya berisi tentang aplikasi yang dijalankan dalam modus gras ( dow. Bagi para pemula sebaiknya membaca secara runut guna memudahkan pemahaman dalam setiap penjelasan. Pada bagian pertama. Buku ini menggunakan Qt sebagai pustakanya. Tidak lupa juga kepada Bapak I Made Wiryana (Gunadarma) yang bersedia memenuhi undangan penulis untuk di- . Juga kepada majalah Infolinux yang telah memberikan bonus CD RedHat 7. yang praktis berperan memberikan kemudahan bagi para pembaca untuk memperoleh sumber daya yang dibutuhkan saat menjalankan contoh program dalam buku ini. buku ini juga menyertakan beberapa pertanyaan dan latihan soal guna menggali potensi yang sudah dimiliki pembaca. bahasa Python. Ucapan terima kasih perlu ditujukan kepada pihak terkait yang sudah membantu kelancaran penyelesaian buku ini. maka ulasan bab demi bab dirangkai dengan tingkat keterkaitan yang tinggi. yaitu menggunakan XWin- tidak disertakan dalam paket standar Python. Pustaka gras untuk membentuk berbagai objek visual graphical user interface ). Kepada keluarga penulis. Sebagai pelengkap.3 di salah satu edisinya. dengan database berbasis SQL yaitu PostgreSQL dan MySQL. Karena merupakan tutorial. ulasan menyangkut bahasa Python beserta pustaka ( Python. Henry (NCS).

DAFTAR GAMBAR posisikan sebagai editor. mudah-mudahan kehadiran buku ini di tengah masyarakat semakin menyemarakkan pasar IT ( nology ) information tech- di Indonesia dan memperluas kesempatan kerja bagi Setidaknya melengkapi rak-rak masyarakat pada umumnya. dan perpustakaan lainnya agar dibaca siapa saja yang bersungguh-sungguh menumbuhkan IT di Indonesia. perpustakaan kampus. rumah. 17 Sekali lagi. kantor. Penulis .

18 DAFTAR GAMBAR .

Bagian I Pendahuluan 19 .

.

21 . terkadang masih dihadapkan pada pertanyaan tentang alasan-alasan kita membuat program. Berikut ini sedikit ulasan seputar dunia pemrograman komputer agar memantapkan motivasi dan memudahkan pemahaman mengapa suatu keputusan telah diambil. khususnya dunia pemrograman. apa manfaat yang bisa diambil.Bab 1 Pemrograman Komputer Bagi mereka yang belum memahami dunia komputer. bagaimana kelanjutannya. dan bagaimana arah teknologi komputer ke depan sehingga investasi waktu dan lainnya dalam mempelajari pemrograman tidak siasia.

karena: • • • • belum ada program yang dapat menyelesaikan permasalahan yang dihadapi program yang ada terlalu mahal program yang ada terlalu berat dimana speskasi komputer yang ada miliki tidak mampu untuk menjalankannya hanya untuk kesenangan Apa yang kita lakukan dengan komputer untuk menyelesaikan masalah yang dihadapi ? • • • Menggunakan program yang sudah ada Menggabungkan program yang sudah ada untuk membentuk suatu fungsi Membuat program baru .1 Mengapa Kita Butuh Program Saat ini ada ribuan aplikasi yang siap pakai untuk berbagai keperluan. PEMROGRAMAN KOMPUTER 1. Mungkin Anda bertanya-tanya mengapa kita harus membuat program ? Bukankah program yang sudah ada dapat kita gunakan ? Sebagaimana tujuan pembuatan komputer itu sendiri. program dibuat untuk: • • mendapatkan jawaban atas suatu masalah memperpendek langkah penyelesaian suatu masalah Lalu mengapa kita perlu membuatnya ? Ya.22 BAB 1.

Pascal. C++.2. Dengan Python dua proses tersebut tidak perlu . 1. Python sebagaimana C.1). Pemrograman tradisional membutuhkan siklus pengembangan yang lebih lama karena harus melalui proses kompilasi dan dilakukan (lihat gambar 1.1. tapi juga dapat digunakan untuk menangani database. linking ke sistem operasi.3 Siklus Pengembangan Program Development cycle atau siklus pengembangan program merupakan hal penting pemilihan suatu bahasa pemrograman. atau Java.2 Bahasa Pemrograman Bahasa pemrograman merupakan cikal bakal suatu program atau aplikasi komputer. BAHASA PEMROGRAMAN 23 1. Ada begitu banyak bahasa pemrograman baik yang digunakan untuk kebutuhan khusus atau juga untuk penyelesaian masalah secara umum. Dengannya Anda bisa merangkai perintahperintah yang sudah ditetapkan untuk membentuk suatu fungsi yang diinginkan. dan bahkan untuk membuat game. Tidak hanya terbatas pada masalah perhitungan matematika. dibuat untuk membuat program dengan berbagai keperluan. ( Bahasa pemrograman untuk kebutuhan khusus misalnya SQL yang khusus dibuat untuk penan- structured query language ) ganan database atau OpenGL yang diperuntukkan untuk membuat grak. grak.

24 BAB 1.1: Siklus Pengembangan Program (development cycle) . PEMROGRAMAN KOMPUTER ../python-pengenalan/siklus.ps Gambar 1../.

1 Mengapa Python Python dapat dijalankan di berbagai sistem operasi seperti Linux.org/doc/Comparisons. Unix. Bahasa-bahasa tersebut ada yang tergolong untuk pembuatan aplikasi umum. Pengurangan source program secara besar-besaran juga merupakan tujuan dibuatnya bahasa ini. dan juga Windows. 2.html 25 .python. namun ada juga yang memang dirancang untuk suatu aplikasi tertentu. Adapun perbandingan Python dengan bahasa lain bisa dilihat di situs internet: http://www.Bab 2 Bahasa Pemrograman Ada banyak bahasa pemrograman yang sudah dibuat sejak diciptakannya komputer pertama kali.

script internet. dan pemrograman database.com/swol-10-1997/swol-10-scripting.sunworld. Belanda.org/doc/essays/comparisons.26 BAB 2. ciri orientasi objeknya membuat Python dapat bagai tools yang berdiri sendiri. Se- 1 Di RedHat Linux program instalasinya ditulis dengan Python .1 antarmuka gras. Python pertama kali dikembangkan oleh Guido van Rossum pada tahun 1990 di CWI. digabungkan dengan modul lain yang dibuat dengan C++.python. Python bukan hanya sekedar bahasa lain untuk membuat aplikasi. Python sudah dipakai untuk system administrator tools. Bahas ini dikategorikan sebagai bahasa pemrograman tingkat tinggi ( bahasa berorientasi objek yang dinamis ( ic language ).python.html http://www. very-high-level language ) dan juga merupakan object-oriented dynamjenis baru. BAHASA PEMROGRAMAN http://www.html#vowels Mungkin bahasa pemrograman ini belum terdengar secara meluas di kalangan programmer Indonesia.html Atau untuk yang bergaya humor ada di: http://www.org/doc/Humor. tapi merupakan sebuah bahasa Secara umum Python menawarkan: • • • • Berorientasi objek Struktur pemrograman yang handal Arsitektur yang dapat dikembangkan ( tanam ( extensible ) dan diembeddable ) dalam bahasa lain Sintaks yang mudah dibaca Sebagai contoh.

Secara umum. Bagi sebagian orang hal ini membuat Python lebih mudah digunakan dan pilihan yang lebih tepat untuk membuat program yang dapat ditulisulang atau dilain. Tcl dirancang sebagai bahasa interpreter yang dapat digabungkan dengan modul yang dibuat dengan C. Python dapat digunakan sebagai bahasa yang digabungkan dengan bahasa lainnya. MENGAPA PYTHON Perl.1. Tidak seperti Tcl. atau Java. Python ringkas dan lebih mudah diba- ca. struktur datanya dan dukungan untuk pemrograman berskala besar membuatnya dapat diterapkan untuk ruang lingkup yang lebih besar. Perl Seperti Perl. shell Tidak seperti Perl.2. Perl merupakan maintenance oleh pihak tools yang handal Namun sekali kita berniat untuk melakukan lebih dari sekedar pengolahan teks dan le. bukan sekedar string processor. 27 Python sering dibandingkan dengan bahasa lain seperti: Tcl. Java . Tcl Seperti Tcl. Python memiliki ciri bahasa pemrograman yang sesungguhnya. Tanpa banyak tanya. Python dapat digunakan untuk membuat tools. untuk sistem administrasi. kemampuan Python sangat menggoda. sedangkan Python dapat melakukan hal yang sama namun ditambah kemampuan orientasi objek.

. Contohnya: Python tidak memerlukan deklarasi tipe data untuk suatu variabel. program Python berjalan lebih lambat ke- timbang Java. yang sebenarnya tidak diketahui pada saat kompilasi.2 Nama Python Sekedar info. penamaan Python bukanlah dikaitkan dengan reptil yang biasa kita kenal. dan dukungannya dengan apa yang dictionary. tapi waktu yang diperlukan untuk membuatnya justru lebih cepat. BAHASA PEMROGRAMAN 2 Secara umum program Python memang lebih lambat ketimbang Java . Lihat halaman 48. Python memeriksa tipe objek a dan b. melainkan diberikan setelah pembuatnya menonton acara BBC Monty Python's Flying Circus. Program Python tiga sampai lima kali lebih ringkas dibandingkan Java.28 BAB 2. Java bisa menerapkan tipe a dan b. array yang memiliki kunci (key). Contoh: ketika ekpresi a+b dievaluasi. integer dan oat secara lebih esien. sifatnya yang late-binding. namun membutuhkan deklarasi untuk 2. elemen disebut pada array3 yang tipenya bisa beragam. 2 Karena lukan. yaitu kode diproses ketika diper- 3 Python menyebutnya list 4 Bisa juga disebut associatve array.4 Karena pemberian tipe data dilakukan saat runtime.

3. Dukungannya akan pemrograman berorientasi objek membuat Python dapat dipakai untuk mengembangkan aplikasi yang kompleks namun tetap konsisten. kecil semakin baik. 2. Memperhatikan tipe data dalam setiap operasinya. Kecepatan Program yang esien biasanya berpengaruh pada kecepatan namun bisa juga sebaliknya. Hal ini dapat dilihat dari sifat Python itu sendiri seperti: 1. Untuk sebuah hasil yang sama dapat ditempuh dengan berbagai cara (baca: algoritma). Tidak ada fasilitas Basic.2. PEMROGRAMAN TERSTRUKTUR 29 2. 3. loncat ke baris tertentu. Penerapan rumus matematika dalam menyelesaikan suatu masalah bisa membuat esiensi dalam penyimpanan data karena bisa menjadi lebih kecil. misalnya yang terjadi pada penyimpanan format gambar JPEG yang Esiensi juga semakin mengarah pada cara penyimpanan data: .3 Pemrograman Terstruktur Pembuatan program yang terstruktur merupakan tujuan dari Python. sebagaimana yang bisa ditemukan dalam GOTO pada pemrograman Sebagai gantinya Anda dapat menerapkan fungsi agar program lebih mudah dibaca dan lebih sistematis. Prioritas berikut bisa dijadikan pedoman dalam menuliskan program: Esiensi Algoritma harus ringkas dan padat.

Anda mungkin sudah membuat algoritma yang ditulis dalam bahasa pemrograman tertentu.30 BAB 2. BAHASA PEMROGRAMAN lebih kecil dari BMP. BMP sangat esor tidak terlalu terbebani. Mempercepat proses debugging 6 5 Penggunaan kembali kode yang sama. Pengembangan Program atau algoritma yang baik harus mudah dikembangkan. Hal ini berkaitan erat dengan kecepatan penyelesaian suatu aplikasi dengan manfaat: 1. namun membutuhkan alokasi memori yang cukup besar. Modular Pilah permasalahan menjadi beberapa bagian agar mudah dalam menyelesaikannya. JPEG sangat baik untuk faktor esiensi tempat ( storage ). maka seharusnya dengan mudah Anda menuliskannya kembali untuk bahasa pemrograman yang lain. Reuseable code 5 merupakan ka- ta yang akan dicapai. Bila Anda menuangkannya secara tepat.4 Dokumentasi Biasakan membuat dokumentasi dalam aktivitas pemrograman Anda. 2. namun prosesor harus simple dan pros- bekerja lebih keras karena proses penerjemahannya (dari data ke gambar) menerapkan rumus matematika yang rumit. 6 Debugging: aktivitas dalam mencari kesalahan suatu program .

DOKUMENTASI 2. 7 Script: baris-baris program 8 Bug: sifat yang salah dari suatu program 9 Option adalah pilihan atau alternatif tertentu gram. dan juga sertakan alamat Anda (kalau berkenan) sebagai referensi bagi komunitas pengguna untuk bertanya. dalam menjalankan pro- . seperti: 1. Memudahkan pengembangan di kemudian hari. option 9 untuk suatu tugas tertentu. Dokumentasi bisa dalam berbagi bentuk tergantung  yang Anda tuju. 3. 2. dan bagaimana langkah pengembangan selanjutnya. Pengguna umum: dokumentasi bisa berupa langkah demi langkah penggunaan program.4. untuk apa.2. atau bisa bug 8 yang sudah Anda ketahui tapi belum sempat diperbaiki. 31 3. System Analyst: tulisannya bisa berupa rancangan umum program. Programmer: dokumentasi bisa berada dalam juga berupa daftar audience  script 7 yang Anda buat untuk menerangkan suatu algoritma. Memudahkan orang lain untuk mempelajarinya sehingga Anda tidak perlu mengutarakannya berulang-ulang.

BAHASA PEMROGRAMAN .32 BAB 2.

ada baiknya Anda memahami beberapa hal teknis tentang bentuk tulisannya. terutama aplikasi database.Bab 3 Teknik Penulisan Sebelum lebih jauh membaca buku ini. Bahasan merupakan yang paling sering diterapkan dalam pembuatan aplikasi. Memperbanyak contoh program dan sebisa mungkin mungkin menghindari gaya buku referensi untuk mempermudah 33 .1 Gaya Gaya penulisan yang diterapkan pada pembuatan buku ini mengutamakan hal-hal berikut: 1. 2. 3.

2 Jenis Huruf dan Simbol Perlu diperhatikan pula huruf dan font yang digunakan dalam buku ini yang mana berkaitan dengan kemudahan dalam memahami kalimat demi kalimat. terutama bagi yang belum terbiasa dengan pemrograman komputer. tipe data. kode program seperti nama variabel. operasi Linux. Meski begitu. penegasan seperti moto atau kata kunci yang biasanya berkaitan dengan pembicaraan seputar konsep atau loso. dsb. Italic Courier Underline perlu diperhatikan atau memperkenalkan istilah dalam bahasa Inggris untuk pertama kalinya. Namun yang perlu Anda ketahui adalah bahwa contoh program yang ada di sini telah dicoba pada sistem 3. TEKNIK PENULISAN pemahaman. daftar isi dan indeksnya sebisa mungkin bisa menjadi referensi ringkas.34 BAB 3. . Tulisan ini sendiri berusaha untuk menghindari hal-hal spesik sistem operasi. Pada script program yang cukup panjang dilengkapi dengan nomor baris untuk memudahkan rujukan dalam pengetikkan kembali (ketika Anda ingin mencobanya). 3. Bisa juga berupa nama le atau program.

beberapa orang sering menyebutnya sebagai DOS Prompt.3. .2. JENIS HURUF DAN SIMBOL dakan perintah tersebut dijalankan di but sebagai 35 Karakter dolar ($) yang mengawali suatu baris perintah menan- command line .1 console atau sering dise- 1 Karena banyak yang terbiasa dengan sistem operasi DOS.

TEKNIK PENULISAN .36 BAB 3.

dalam C++ library untuk mengakses database PostgreSQL qt-PostgreSQL melalui Qt 37 .Bab 4 Persiapan Juga ada beberapa hal yang perlu dipersiapkan untuk menjalankan contoh program yang ada.1 Paket Program Ada beberapa paket program dalam bentuk RPM yang perlu dipasang ( yaitu: install ) sebelum mengikuti pembahasan buku ini. python qt interpreter Python library utama Qt. 4.

Untuk pengguna KDE dapat menggunakan vi atau pico dalam console environkate. atau Anda dapat menggunakan gedit pada Gnome. 4.38 BAB 4. Pada distribusi Linux lainnya bisa jadi namanya berbeda. Sebagai informasi saja bahwa . dakan dengan warna objek dalam script Python seperti reserved 1 kata resmi yang digunakan dalam bahasa Python sehingga tidak boleh digunakan sebagai nama variabel.2 Text Editor ment .tidak ada yang perlu di-download lagi dari internet untuk mengikuti contoh program pada buku ini.dengan CD tersebut . dsb.3 yang terdiri dari 3 CD. . PERSIAPAN library untuk mengakses database MySQL melalui Qt qt-MySQL PyQt library untuk menggunakan Qt dalam Python Nama paket di atas penulis dapatkan dari RedHat 7. kwrite Sebagai tambahan vi dan kwrite da- pat mengenail perintah Python dimana keduanya akan membe- word1 . integer. string.

Bagian II Python 39 .

.

py 41 .Bab 5 Hello World Hello world sudah merupakan tema standar dalam permulaan Makna dibelakangnya belajar sebuah bahasa pemrograman. adalah bagaimana menampilkan pesan tersebut dengan menggunakan bahasa yang tengah kita pelajari.py dengan text editor pilihan Anda: $ kwrite halo. Buatlah sebuah le halo.py Lalu ketikkan baris berikut: print "Hello world !" Simpan le ini dan jalankan: $ python halo.

Python mengenal apa yang disebut blok program. 5. Selamat. HELLO WORLD Hello world ! dimana perintah print tersebut akan mencetak ke layar.1. Baris-baris berikut dianggap sebuah blok program: print "Hello world !" print "Salam dunia !" Anda tidak boleh menuliskannya seperti ini: print "Hello world !" print "Salam dunia !" Karena pesan kesalahan berikut akan tampil: .1 Aturan Penulisan Keunggulan Python dibandingkan bahasa pemrograman sejenis lainnya adalah script-nya yang lebih mudah dibaca. kini Anda telah menjadi seorang programmer Python dan mari melanjutkannya dengan hal yang lebih menarik lagi. Kemudahan ini bahkan berasal dari aturan main dalam penulisan sintaksnya seperti pembahasan berikut ini.42 BAB 5. 5.1 Indent Sebagaimana bahasa pemrograman pada umumnya.

Contoh tersebut adalah blok program utama.1. . ATURAN PENULISAN File "halo. line 2 print "Salam dunia" ^ SyntaxError: invalid syntax 43 Dimanakah letak perbedaannya ? Menurut Python.2 Baris Perintah Pergantian baris (dengan menekan Enter) merupakan pemisah antara dua baris perintah. Baris berikut print "Hello world !" dikatakan sebuah baris perintah. 5. dan print "Salam dunia !" juga merupakan sebuah baris perintah.1. Perhatikan baris kedua di atas dimana ada selisih satu karakter dengan baris sebelumnya.5. Mungkin Anda yang terbiasa dengan Pascal atau PHP jelas merasakan perbedaan dengan cara penulisan ini dimana kedua bahasa tersebut tidak akan menjalankan sebuah baris perintah kalau belum diakhiri titik koma (.py".). sebuah blok program harus dalam sebuah margin . Anda dapat menjumpai sub-blok dalam pembahasan lainnya seperti pada Bab Kondisi di halaman 51.

3 Keterangan Program Sebelumnya disebutkan bagaimana pentingnya dokumentasi dalam pemrograman." 5.44 BAB 5. print "Baris ini sangat panjang sehingga \ perlu ditulis dalam beberapa baris agar \ memudahkan pencetakan nanti. Anda dapat meng- gunakan karakter backslash (\) untuk memberitahu Python bah- wa baris tersebut belum berakhir.1." # Jawabannya Selain itu bisa juga menggunakan tiga kutip ganda: """ Oleh : Email : Tanggal: Manfaat: """ print "Salam" Owo Sugiana sugiana@rab. HELLO WORLD Untuk sebuah baris yang terlalu panjang.id 17-1-2003 Mencetak salam . Anda dapat menggunakan karakter cross (#) untuk membuat komentar dalam script: # Tanya kabar print "Apa kabar ?" atau bisa juga dituliskan disampingnya: print "Kabar baik.co.

VARIABEL 45 5. Aug 7 2000.5.3 Modus Interaktif Baris program juga dapat ditulis langsung dalam modus interaktif ( interactive mode ). Python juga memberikan keluwesan dalam deklarasi variabel ini. n = 1 n = "Saya belajar Python.2 Variabel Python tidak membutuhkan deklarasi variabel secara khusus sebagaimana beberapa bahasa pemrograman lainnya. Cara ini biasanya digunakan untuk melakukan eksperimen pendek.5.2. dan pada baris berikutnya n berubah tipe menjadi string.2 (#1. $ python Python 1. Deklarasi cukup dengan memberikan nilai awal seperti contoh berikut: n = 1 yang menunjukkan variabel n bertipe integer (bilangan bulat)." Baris pertama mendeklarasikan n bertipe integer. 21:22:50) [GCC 2.95.2 19991024 (release)] on linux2 . Variabel yang sama dapat berubah-ubah tipe datanya meski dalam sebuah script. 5.

yaitu pada penampilan nilai. HELLO WORLD > > > print "Hello world !" Hello world Copyright 1991-1995 Stichting Mathematisch Centrum.46 BAB 5. lukan print Anda tetap memer- untuk menampilkannya. print 5+7 . Amsterda Jadi bila Anda menemui prompt >>> berarti baris program dijalankan melalui modus interaktif ini. Sedikit perbedaan antara modus interaktif dengan penggunaan le. Penjumlahan berikut bisa langsung tampil hasilnya pada modus interaktif > > > 5+7 12 tapi tidak terjadi bila menggunakan le.

in ? TypeError: number coercion failed dimana sebuah bilangan ditambahkan dengan sebuah string. Python sangat memperhatikan tipe data.Bab 6 Tipe Data Meski tidak memerlukan deklarasi secara khusus. 47 . Selanjutnya akan diterangkan tipe data yang sering dipakai dalam pembuatan aplikasi nanti. line 1. Anda tidak diperkenankan melakukan hal ini: > > > 5 + "1" yang bisa menimbulkan pesan kesalahan berikut: Traceback (innermost last): File "<stdin>".

imal. . namun tidak dibahas disini.48 BAB 6.1 Bilangan Bilangan atau angka merupakan hal yang biasa kita temui dalam matematika.0 menyatakan bahwa pakan nilai. > > > n=7.1.1 berisi beberapa operator bilangan yang sering dijumpai pada operai matematika. Tabel 6. 1 > > > n=7 >>> n 7 menyatakan n bertipe integer dengan nilai 7. TIPE DATA 6.1 Operator Operator merupakan pengolah variabel atau nilai. Python mengenal dua tipe data bilangan: bilangan bulat (integer) dan bilangan pecahan (oat). > > > 10+5 15 > > > 12*6 72 1 Python juga mengenal bilangan imaginer. Dikatakan juga bahwa n bertipe oat karena mengandung titik desn merupakan variabel dan 7 meru- 6.0 7.

6 maka salah satunya harus oat: > > > 8. 6.6 Fungsi matematika lainnya terdapat dalam modul math.6 atau bisa juga menggunakan fungsi float(): > > > float(8)/5 1.6.1.1. BILANGAN Catatan 49 Dengan hasil yang langsung ditampilkan seperti di atas maka Anda juga dapat menjadikan modus interaktif ini sebagai kalkulator. bila kedua bilangan merupakan integer maka hasilnya pun integer. Sedikit catatan untuk operator bagi (/). > > > 8/5 1 Apabila ingin mendapatkan nilai 1.2 Pengelompokan Operasi Sangat mungkin terdapat beberapa operasi terdapat dalam satu baris: >>> 8 + 5 * 2 18 .0/5 1.

b kali * a * b bagi / a / b sisa bagi % a % b pangkat ** a ** b Tabel 6.50 BAB 6.1: Operator Bilangan . TIPE DATA Operator Simbol Contoh tambah + a + b kurang a .

1.0 6. misalnya: .3 Pembulatan Pembulatan bilangan pecahan bisa menggunakan fungsi dan round(). BILANGAN erator.0 > > > n=17. Jika Anda ingin sebaliknya gunakan tanda kurung untuk pengelompokan operasi: > > > (8 + 5) * 2 26 6.1. Perbedaannya adalah bawah.5 > > > int(n) 17 > > > round(n) 18.6.4 Bentuk Tampilan Untuk mencetak laporan tentu diperlukan tampilan yang baik.49 int(n) > > > round(n) 17. baru selanjutnya penjumlahan. > > > n=17.1. sedangkan round() int() int() membulatkan ke- membulatkan ke bawah bila bagian pecahan (desimal) lebih kecil dari 0. 51 namun Anda perlu memperhatikan prioritas masing-masing opPada contoh di atas Python mendahulukan operasi perkalian.5 namun bila sebaliknya akan membulatkan ke atas.

234. 1234.345 2.56' . > > > locale.format("%. 1234. Ada pemisah ribuan.345. contoh: 2.2f" menunjukkan jumlah desimal yang akan tampil. Angka 1 pada masukan terakhir pada fungsi format() me- nunjukkan apakah angka akan ditampilkan dengan pemisah ribuan. > > > locale.2f".567.setlocale(locale. "") 'id_ID' id_ID berarti Indonesia.2f".format("%.57' Angka 2 pada "%. TIPE DATA 1.67 Program kecil berikut akan menampilkan angka sesuai kriteria di atas. Cobalah ganti dengan angka terakhir lebih kecil dari 5: > > > locale. Kalau Anda lihat hasilnya maka dapat diambil kesimpulan bahwa 1234.234. lalu gunakan format() untuk menampilkan angka dengan pemisah ribuannya. Hanya dua angka desimal di belakang koma.56' maka format() melakukan pembulatan ke bawah.564) '1234.567 telah dibulatkan desimalnya dari 3 angka menjadi 2 dengan pembulatan ke atas. 1) '1. contoh: 2. 1234.52 BAB 6.format("%.LC_ALL.564. > > > import locale > > > locale. 1) '1.2f".

> > > 'telur dadar' 'telur dadar' > > > "bolu kukus" 'bolu kukus' Menuliskan kutip dalam suatu string harus diawal bila jenis kutipnya sama: backslash (\) > > > 'doesn\'t' "doesn't" atau bisa juga tanpa backslash bila kutipnya berbeda: > > > "doesn't" "doesn't" . STRING Modul locale locale 53 adalah modul yang berkaitan dengan setting negara. baik kutip ganda maupun tunggal. Setting ini bisa Anda Maka tidak heran kalau pemisah ribuan dan pemisah desimal tampil sesuai dengan gaya Indonesia. Selain angka. Python juga dapat menangani string dengan berbagai cara. temui di awal instalasi sistem operasi.6.2. 6.2 String String merupakan kalimat yang diawali dan diakhir dengan kutip. String dapat diapit baik oleh kutip tunggal maupun kutip ganda.

' >>> c = a + ' ' + b > > > print c Bahasa saya adalah Python. -H nama-host Nama host yang akan dihubungi .1 Penjumlahan & Perkalian Beberapa string dapat digabung dengan menggunakan operator + (penjumlahan) berikut: > > > a = 'Bahasa saya' > > > b = 'adalah Python. . 6.. -h Tampilkan bantuan ini .2. TIPE DATA String juga dapat ditulis dengan awalan tiga buah kutip (baik kutip tunggal maupun ganda) dimana akhir string juga dinyatakan dengan tiga kutip juga. Cara pakai: kontak [OPTIONS] ....54 BAB 6.... karena tidak memerlukan backslash (\). > > > print """ .. """ Cara pakai: kontak [OPTIONS] -h Tampilkan bantuan ini -H nama-host Nama host yang akan dihubungi >>> Keuntungan cara ini adalah memberikan kebebasan penulisan string bila lebih dari satu baris.

2. STRING dan juga digandakan dengan 55 * (perkalian): > > > '-' * 10 '----------' 6.c) > > > print s 1 + 2 = 3 dan dengan demikian juga mempercepat proses debugging. namun pengisian variabel s menyulitkan pembacaan program. Gantilah menjadi seperti ini: > > > s = "%s + %s = %s" % (a. str() untuk mengubah variabel bertipe apa Python >>> a = 1 >>> b = 2 >>> c = a + b > > > s = str(a) + " + " + str(b) + " = " + str(c) > > > print s 1 + 2 = 3 Meski cara di atas sudah benar.2 String Format Anda sudah mengetahui cara menggabungkan string.6.2.b. Tapi bagaimana kalau angka digabungkan dengan string ? menyediakan fungsi saja menjadi string. .

9") 8.2.len() Fungsi len() akan mengembalikan integer yang menunjukkan jumlah karakter dalam suatu string: > > > len("siap") 4 . 6.2.float() float() mirip dengan int() di atas.2. fungsi kegunaan lain. int() digunakan untuk mengubah 6.9 Proses perubahan dari suatu tipe data ke tipe data lainnya ini sering disebut sebagai konversi atau cast .4 String Menjadi Float .56 BAB 6.5 Panjang String . Contoh di atas menunjukkan int() yang dibahas sebelumnya digunakan unint() memiliki 6. tuk pembulatan. > > > float("8. > > > int("9") 9 Memang. TIPE DATA str().int() Kebalikan dari fungsi string menjadi bilangan integer.3 String Menjadi Integer . hanya saja ia mengemba- likan bilangan bertipe oat.

dan b[1] bertipe integer.3 List List sering disebut sebagai array atau larik (dalam bahasa Indonesia) adalah kumpulan data dimana setiap data memiliki nomor index yang dimulai dari 0. > > > a = [9.append() & insert() List sebenarnya merupakan objek dimana ia memiliki beberapa fungsi.1 Penambahan . > > > c = [] .1991] > > > b[0] 'Python' > > > b[1] 1991 dimana b[0] bertipe string. LIST 57 6. 6.6.5] > > > a[0] 9 > > > a[1] 8 Python juga memperbolehkan setiap elemen data memiliki tipe yang berbeda: > > > b = ['Python'.7. Misalnya fungsi untuk menambah elemen data.6.3.3.8.

4.2.5] > > > del a[3] >>> a [1.58 BAB 6.3.999.3.2.append('persen') >>> c [100.1.insert( (2.888) ) >>> a [0.4. TIPE DATA c merupakan list hampa dimana tidak ada elemen data di dalamnya.2.1.del Perintah del digunakan untuk menghapus elemen data: > > > a = [1. Untuk menambahkannya gunakan fungsi append().3.999.3. 'persen'] Perintah insert() dapat digunakan untuk menyisipkan: > > > a = [0. > > > a.2.999) ) >>> a [0.2.insert( (10.append(100) > > > c.1. > > > c.3. .888] 6.2 Penghapusan .4] > > > a.4] Kalau nomor index melampaui nomor index maksimum maka hasilnya sama saja dengan penggunaan append().3.5] yang berarti menghapus elemen data pada nomor index 3.

3. Cara terbaik untuk mengingat bagaimana pemenggalan bekerja adalah dengan berasumsi bahwa angka index berada diantara dua karakter. > > > d = 'Python' > > > d[0] 'P' > > > d[5] 'n' 6.2 jumlah elemen data yang ada di dalamnya.len() Anda dapat menggunakan fungsi jumlah elemen dalam list: len() untuk mendapatkan > > > d = ["Jeruk". "manis"] > > > len(d) 2 2 Lihat gambar 6.3 String Sebagai List String juga dapat diperlakukan sebagaimana list. LIST 59 6.3.6.1.4 Pemenggalan Pemenggalan ( slice ) suatu list bertujuan untuk mengambil seLihat tabel 6. 2 6. . atau lebih tepatnya list of character (list yang elemen datanya terdiri dari satu karakter). sebagai contoh.5 Panjang List .3.3.

60 BAB 6.2: Contoh pemenggalan list . TIPE DATA Variabel Hasil Keterangan d 'Python' nilai awal d[0] 'P' karakter pertama dari kiri d[2:] 'thon' d[:2] 'Py' d[-1] 'n' mulai karakter ketiga dari kiri dua karakter pertama dari kiri karakter pertama dari kanan d[-2:] 'on' d[:-2] 'Pyth' d[2:5] 'tho' mulai dua karakter pertama dari kanan mulai karakter pertama dari kiri hingga sebelum karakter ke dua dari kanan karakter ketiga hingga kelima dari kiri Tabel 6.

Sehingga kita dapat membuat list dalam list atau disebut juga list multidimensi. > > > mhs = [[2001. 6 (total > > > len(mhs) 3 Gunakan nomor index 0 untuk mendapatkan record pertama: .3.3."Yuli"].6 List Dalam List Tipe data untuk setiap elemen list bisa apa saja."Gani"]] Struktur mhs di atas menyerupai sebuah tabel dimana terdapat Menurut Anda berapa jumlah maTentu Anda tidak ingin menjawab ID dan nama mahasiswa."Hery"].6.[2002. hasiswa di atas ? jumlah elemen data).[2003. termasuk tipe list itu sendiri. LIST +---+---+---+---+---+---+ | P | y | t | h | o | n | +---+---+---+---+---+---+ 0 -6 1 2 3 4 -2 5 -1 6 61 -5 -4 -3 Gambar 6.1: Nomor index pada list 6.

> > > a = [9.3] > > > a. dan [1] adalah nomor kolom. 'Hery'] sedangkan untuk mendapatkan eld kedua (nama) dalam record tersebut: > > > mhs[0][1] 'Hery' List dua dimensi ini dapat juga dikatakan sebagai struktur data tabel yang terdiri dari baris dan kolom.3.reverse() >>> a [3.reverse() Urutan elemen dalam list bisa dibalik dengan menggunakan fungsi reverse().3] > > > a. atas Jadi pada contoh di [0] adalah nomor baris.8.7 Membalikkan Urutan .4.8. TIPE DATA > > > mhs[0] [2001.sort() sort() digunakan untuk mengurutkan list dari yang terkecil ke yang terbesar ( ascending ): > > > a = [9.sort() . 6.4. 9] 6.3.62 BAB 6.8 Mengurutkan . 4. 8.

3] >>> b = a karena itu hanya membuat b sebagai nama lain dari bisa dibuktikan setiap perubahan pada a maka b a saja.6. > > > a = [9.4. 4. 3. 9] 63 Sedangkan untuk mengurutkan dari yang terbesar ke yang terkecil ( descending ) bisa menggunakan kombinasi sort() dan reverse(). 8.4. Ini juga berubah > > > a. 4.8. 4. 3. 7] Fungsi list baru hasil salinan dari list() dapat digunakan agar b benar-benar merupakan a. LIST >>> a [3. 8.reverse() >>> a [9.append(7) >>> a [9. 8.3] > > > a. 8. 4. 3] 6.9 Menyalin .8. .3.3. 7] >>> b [9.sort() > > > a.list() Menyalin suatu variabel list ke variabel lainnya tidak bisa dengan cara seperti ini: > > > a = [9.

64 BAB 6.2. 3. "Rusly". 1003:"Endro"} "Andre". dan "Endro" merupakan values (nilai).ia tidak diurutkan berdasarkan index angka (0. Setiap elemen data dalam dictionary memiliki kunci ( key ) dimana satu sama lain bersifat unik. atau list. dan 1003 disebut sebagai keys (kunci). 7] >>> b [9.4. 1002. . oat. 3] 6.Key & Value Dictionary sering disebut sebagai associative arrays dimana - tidak seperti array . 1002:"Rusly". 8. string juga bisa.append(7) >>> a [9. tuk mendapatkan nilai-nilai tersebut perlu mengetahui 1001.8. > > > mhs = { 1001:"Andre".3] > > > b = list(a) > > > a.1. sedangkan key -nya: Un- > > > mhs[1001] 'Andre' Tipe data dengan tipe keys tidak harus integer. 4. 4. Bahkan data untuk keys dan values tidak harus seragam antara elemen yang satu dengan yang lainnya.3). begitu juga values yang bisa berupa integer. TIPE DATA > > > a = [9. 8.4 Dictionary .

KEY & VALUE 65 > > > data = { "a":1990.2 Daftar Nilai . 9:"sembilan".values() values() digunakan untuk memperoleh keseluruhan nilai dalam dictionary. 'Andre'] 6. dictionary juga merupakan objek yang memiliki fungsi.2.keys() Gunakan fungsi keys() untuk memperoleh keys dari dictionary.4.1 Daftar Kunci .4. DICTIONARY . 6.6. 1001] 6. > > > mhs. > > > mhs. 1002.4."c".4.update() update() data.3 Menambah Atau Mengubah Nilai ."x"] } > > > data["a"] 1990 Sebagaimana list. "test":[1. digunakan untuk menambah atau mengubah elemen > > > mhs = {} {} adalah dictionary hampa . 'Rusly'.values() ['Endro'.keys() [1003.

Hal ini terlihat dari banyaknya fungsi yang dimiliki oleh suatu variabel.66 BAB 6.6 Daftar Fungsi Suatu Objek .type() Fungsi type() digunakan untuk mengetahui tipe suatu nilai: > > > type(7.5 Mengetahui Tipe Data .4 Menghapus .update({1004:'Eko'}) > > > mhs {1004: 'Eko'} 6. TIPE DATA > > > mhs.del Untuk menghapus elemen dalam dictionary bisa menggunakan perintah del.dir() Beberapa variabel pada contoh sebelumnya merupakan objek. > > > del mhs[1004] > > > mhs {} 6.0) <type 'float'> 6.4. Untuk mengetahui fungsi apa saja yang ada dapat dilihat dengan menggunakan fungsi dir(): > > > a = [] .

'remove'. 'reverse'. 'count'. 'insert'. 'pop'.6. 'extend'. DAFTAR FUNGSI SUATU OBJEK . 'index'.DIR() 67 > > > dir(a) ['append'.6. 'sort'] .

68 BAB 6. TIPE DATA .

Bab 7 Kondisi if menyatakan bila pada saat kondisi tertentu tercapai maka apa yang akan dilakukan." n = raw_input("Yakin (y/t) ? ") 69 . untuk menulis script Sekarang mulailah menuliskan program pendek berikut untuk memahami bagaimana if bekerja. print "Jika Anda tidak yakin saya diam saja. ada baiknya kini Anda menggunakan seperti vi kwrite text program. tidak lagi dalam interactive interpreter . sehingga tema ini sering disebut sebagai jika-maka. Karena penulisan if melibatkan blok program lebih atau editor dari satu.

maka posisi kolomnya harus utamanya.. sehingga n == "y" diban sama dengan "y".. Operator == menyatakan persamaan. KONDISI if n == "y": print "Baiklah" raw_input() digunakan untuk menerima masukan dari pemakai. Sub-Blok Program Perhatikan baris Baris ini disebut sebagai print "Baiklah" tampak menjorok ke dalam. if menandakan baris tersebut if n == "y": print "Baiklah" print "Siapkan perlengkapannya" print ". sub-blok dimana if merupakan blok if." selalu dijalankan meski n == "y" tidak terpenuhi. Jangan lupa untuk menyertakan titik dua (:) pada akhir baris if.. . ca Fungsi ini mengembalikan nilai string. Jika Anda ingin menyertakan baris program lainnya masih termasuk dalam sub-blok sama dengan posisi sebelumnya seperti pada contoh berikut: if n == "y": print "Baiklah" print "Siapkan perlengkapannya" Baris lain yang sejajar dengan merupakan blok utama." Sehingga print ".70 BAB 7..

1. list [1. string "a". -100. Perhatikan script berikut ini: yang akan menampilkan pesan "Salah".7. belumnya dapat ditulis seperti ini: Jadi contoh program se- print "Jika Anda tidak yakin saya diam saja.2. Misalnya angka 0. objek na true (benar) seperti angka 1. false (salah). dsb. dan baris berikut if 1: print "Benar" else: print "Salah" akan menampilkan pesan "Benar". list [ ]." n = raw_input("Yakin (y/t) ? ") yakin = n == "y" if yakin: print "Baiklah" dan kalau Anda tampilkan variabel maka Anda mendapatkan angka 1 atau 0. if 0: print "Benar" else: print "Salah" None. BENTUK LOGIKA 71 7. string Kondisi sebaliknya berarti bermak- dst.1 Bentuk Logika Secara umum semua tipe data yang menyatakan kehampaan dianggap memiliki logika "".3]. tergantung nilai yakin dengan print yakin n. .

kita berangkat" else: if n == "t": print "Kita perlu latihan lagi" else: print "Pilihannya y atau t" . y dan t dimana Anda n = raw_input("Apakah Anda yakin (y/t) ? ") if n == "y": print "Baiklah.elif Pemakai bisa jadi menjawab selain huruf perlu mengantisipasi hal ini. n = raw_input("Apakah Anda yakin (y/t) ? ") if n == "y": print "Baiklah.72 BAB 7.else else digunakan untuk menyatakan kondisi perlawanan dari if. Bisa juga dikatakan bahwa jika suatu kondisi tidak terpenuhi maka jalankan perintah lainnya. 7.2 Selain Itu . kita berangkat" else: print "Kita perlu latihan lagi" Jadi kalau n tidak sama dengan "y" maka baris print "Kita perlu latihan lagi" yang akan dijalankan. KONDISI 7.3 Selain Itu Jika .

kita berangkat" elif n == "t": print "Kita perlu latihan lagi" elif n == "d": print "Diam ni yee" else: print "Pilihannya y.7. atau d" 7. .4. t. kita berangkat" elif n == "t": print "Kita perlu latihan lagi" else: print "Pilihannya y atau t" elif juga bisa ditulis kembali untuk memeriksa kondisi berikutnya. n = raw_input("Apakah Anda yakin (y/t/d) ? ") if n == "y": print "Baiklah. Operator perbandingan lainnya dapat Anda lihat di tabel 7.1.4 Operator Perbandingan Operator == dikategorikan sebagai operator perbandingan un- tuk menyatakan sama dengan. OPERATOR PERBANDINGAN Namun dengan 73 elif script di atas bisa ditulis seperti ini: n = raw_input("Apakah Anda yakin (y/t) ? ") if n == "y": print "Baiklah.

KONDISI Contoh Keterangan a == b a sama dengan b a < b a lebih kecil dari b a > b a lebih besar dari b a != b a tidak sama dengan b a >= b a lebih besar atau sama dengan b a <= b a lebih kecil atau sama dengan b a in c a termasuk dalam list c Tabel 7.1: Operator Perbandingan .74 BAB 7.

Apabila tidak ada huruf yang dimasukkan berarti n merupakan string hampa. 7.1 Bukan . 1 Lihat halaman 52 mengenai bentuk logika.5.5.not not digunakan untuk negasi (perlawanan) suatu bentuk logika. dan or."Y"]: print "Baiklah" 75 Catatan Meski pertanyaannya meminta pemakai untuk mema- sukkan huruf y atau t dalam huruf kecil namun kita perlu mengantisipasi capslock pada keyboard sedang aktif.5 Operator Logika Sebagaimana bilangan atau string. OPERATOR LOGIKA n = raw_input("Yakin (y/t) ? ") if n in ["y". and. suatu kondisi juga memiliki operator yang disebut operator logika yaitu not. 7.1 n = raw_input("Masukkan huruf : ") if not n: print "Kok kosong ?" else: print "Anda memasukkan huruf " + n Pada saat program dijalankan Anda diminta memasukkan huruf apa saja dan diakhiri dengan penekanan Enter. .7.

n = raw_input("Apakah Anda yakin (y/t) ? ") if n == "y" or n == "Y": .or Operator or menyatakan bahwa true tercapai bila salah satu kondisi terpenuhi. yaitu apabila proses konversi dari string ke integer gagal.5.3 Salah Satu Kondisi Terpenuhi .5. Sedangkan kondisi kedua adalah apabila int(n) habis dibagi 2. KONDISI and semua kondisi harus terpenuhi untuk men- 7. n = raw_input("Masukkan bilangan ganjil : ") if n and (int(n) % 2): print "Benar" else: print "Bukan" Kondisi pertama adalah apabila n terisi (bukan string hampa).76 BAB 7.and Dengan operator capai true .2 Semua Kondisi Terpenuhi . Contoh berikut meminta pemakai memasukkan bi- langan ganjil. Untuk menangkap kesalahan konversi tersebut Anda bisa menggunakan has pada halaman 73. misalnya dengan memasukkan huruf. Catatan Penggunaan int(n) juga bisa menimbulkan kesala- han yang tidak dapat ditangani script di atas. try yang diba- 7.

" else: print "Kita cari alternatif lain.7.5. OPERATOR LOGIKA print "Bagus." 77 .

78 BAB 7.2: Operator Logika . KONDISI a b not a a and b a or b 1 1 0 1 1 1 0 0 0 1 0 1 1 0 1 0 0 1 0 0 Tabel 7.

Banyaknya perulangan ini bisa ditentukan di awal berlangsung. Kondisi yang dimaksud .Loop Perulangan ( loop ) adalah menjalankan proses sampai suatu konloop maupun selama loop disi terpenuhi.tentunya .akan mempengaruhi seberapa banyak proses tersebut dijalankan. 8.Bab 8 Perulangan .for for merupakan perulangan sebanyak elemen data dalam suatu list.1 Jumlah Perulangan Ditetapkan .3]: print nomor 79 .2. Perhatikan contoh berikut: for nomor in [1.

2.LOOP for akan menghitung satu persatu setiap elemen dalam [1.2. Dengan demikian script di atas menghasilkan output sebagai berikut: 1 2 3 for memang bekerja dengan list.80 BAB 8. 3] bisa merupakan list berisi data lainnya. Untuk menampilkan list multidimensi kita membutuhkan for Misalkan struktur tabel yang merupakan list dua dimensi. "Jeruk". ia: 1. PERULANGAN . 3750 ] . Menjalankan print nomor sesaat setelah point 1 dijalankan. Selama proses menghitung itu. "Jeruk". for un- tabel = [ [ 2769. 5500 ]. maka diperlukan dua tuk menampilkan isi setiap elemen datanya. 2. 5500 ] for nilai in record: print nilai. record = [ 2769. sehingga list [1. print Koma pada print berarti tidak berganti baris. [ 8205. "Mangga".3]. Memberi nilai dari setiap elemen data ke variabel nomor. di dalam for sebanyak dimensi tersebut.

2] dan for begitu seterusnya.1.4). JUMLAH PERULANGAN DITETAPKAN . untuk mendapatkan Fungsi ini sering dipakai dalam jumlah perulangan yang diinginkan. print range() range() 81 merupakan fungsi yang mengembalikan daftar bilan- gan integer secara berurutan dimulai dari nol. Namun faktorial 0 atau lebih kecil lagi (negatif ) hasilnya tetap 1.1. for nomor in range(3): print nomor dimana output yang dihasilkan adalah: 0 1 2 Bila kisaran yang diinginkan adalah 1-3 maka gunakan range(1. Latihan Tampilkan nilai faktorial 1 pada saat runtime.3. range(5) berarti [0.2. banyaknya sesuai dengan jumlah yang diinginkan. range(3) berarti [0.8.4].FOR ] for record in tabel: for nilai in record: print nilai. 1 Bilangan faktorial n biasa ditulis dengan n! .1. n dimana n dimasukkan Contoh: faktorial 5 adalah 5 x 4 x 3 x 2 x 1 = 120.

Ikuti langkah berikut untuk hasil yang sama dengan contoh menggunakan while: for sebelumnya.5: import random i = 0 while i <= 0.447331794014 .335857508686 0.while while nya ditentukan oleh suatu kondisi.5: i = random. Contoh berikut akan menampilkan bilangan acak yang dibuat terusmenerus sampai ditemukan bilangan yang lebih besar dari 0.random().321183281272 0. PERULANGAN . namun kini i = 0 while i < 3: i = i + 1 print i Script di atas memang lebih pas bila dengan for.82 BAB 8. print i dengan contoh hasil sebagai berikut: 0.42870775016 0.2 Selama .LOOP adalah bentuk perulangan dimana jumlah perulangan- 8.135330567072 0.

WHILE 0. pasti Anda akan menemukan hasil yang berbeda.8. Coba jalankan sekali lagi. import time print time. dalam suatu modul terdapat konstanta __doc__ yang merupakan dokumentasi. waktu dan Ada banyak modul lainnya yang dis- ertakan dalam paket Python seperti time untuk penanganan string untuk penanganan string. Contoh: hat daftar fungsi maupun konstanta yang terdapat dalam suatu modul dengan menggunakan fungsi import random print dir(random) Kalau Anda beruntung.karena sifat bilangan acak itu sendiri.854292081945 lebih kecil dari 0.2. Kini sudah jelas. SELAMA . Anda dapat melidir().287945799635 0.__doc__ . Perhatikan nilai setiap barisnya dimana program tidak akan berhenti sampai ditemukan kondisi yang dimaksud yaitu 0.854292081945 83 Hasil di atas sangat mungkin berbeda dengan yang Anda peroleh . untuk menerapkan algoritma tersebut perulangan for tidak dapat digunakan karena jumlah perulangan yang tidak menentu.5. Modul random random adalah modul tambahan untuk hal-hal yang berkaitan dengan bilangan acak.

print i if i > 0. Tentu saja Anda boleh menggunakan kombinasi while.5. 2 Lihat pembahasan bentuk logika di halaman 52. n n bilangan acak yang for dan diisi pada saat runtime. Tampilkan satu bilangan acak yang lebih kecil dari 0. .5. 2.5: break print "selesai" Perhatikan angka 1 diatas yang merupakan kondisi benar2 .random(). PERULANGAN . Pada contoh di atas dibuktikan dengan dijalankannya print "selesai". karena akan dihentikan dengan perintah break.LOOP 8. Melanjutkan sebelumnya.break Perulangan juga bisa dihentikan dari dalam. De- ngan kata lain perulangan akan dijalankan terus-menerus tanpa henti. import random while 1: i = random. yaitu menggunakan perintah break. Latihan 1. selanjutnya proses kembali ke blok utama.84 BAB 8. break hanya menghentikan perulangan.3 Keluar Dari Perulangan . tampilkan lebih kecil dari 0.

Anda sudah menggunakan fungsi seperti len()." "-" * 10 "Juga diakhiri garis." "-" * 10 Tampak dalam script di atas bahwa print "-" * 10 85 .Bab 9 Fungsi Pada contoh-contoh program sebelumnya. dan random() dimana tujuan pembuatan fungsi adalah mempersingkat penulisan suatu blok program yang dipakai berulang-ulang. Misalnya pada program berikut: print print print print print "-" * 10 "Setiap pesan diawali garis. range().

Misalkan kita ingin membuat garis dengan panjang berbeda-beda def garis(n): print "-" * n garis(10) print "Setiap pesan diawali garis. Contoh berikut akan kita ganti dengan pemanggilan fungsi: # Deklarasi fungsi def garis(): print "-" * 10 # Program utama garis() print "Setiap pesan diawali garis. 9." garis() print "Juga diakhiri garis. namun fungsi yang digunakan tetap sama. Perhatikan posisi kolom source fungsi di atas yang menjorok ke dalam. FUNGSI ditulis berulang-ulang." ." garis() def menyatakan awal deklarasi suatu fungsi.1 Nilai Masukan Fungsi tersebut dikatakan fungsi statis karena ia tidak bisa menerima masukan dari baris program yang memanggilnya.86 BAB 9.

return Fungsi juga dapat mengembalikan suatu nilai sebagaimana yang pernah kita temui pada nya." garis("*"." garis(". def garis(k.10) "Setiap pesan diawali garis.10) 9. dan random() sebelum- digunakan untuk tujuan tersebut. NILAI KELUARAN .RETURN garis(3) print "Juga diakhiri garis.2 Nilai Keluaran .10) print "Setiap pesan diawali garis.9.".n): return k * n print print print print garis("-".2.n): print k * n garis("-"." .3) print "Juga diakhiri garis." garis(". tidak hanya "-". range(). return len()." garis(10) 87 Fungsi juga dapat menerima masukan lebih dari satu.3) "Juga diakhiri garis. def garis(k.". Misalkan karakternya bisa diganti-ganti.

88 BAB 9. Contohnya pada fungsi faktorial() berikut ini: def faktorial(n): if n <= 1: return 1 else: return n * faktorial(n-1) print faktorial(5) . perintah lain di bawah baris (masih dalam fungsi yang sama) tidak akan diproses.n): return k * n print "Selesai" Baris didahului oleh fungsi. print "Selesai" tidak akan dijalankan karena sudah return yang menyebabkan proses keluar dari return sebenarnya None. sebagaimana baris mubazir yang terdapat pada contoh berikut ini: def garis(k.10) return Sebagai tambahan. Fungsi yang tidak menggunakan pakan objek hampa. yaitu 9. None meru- tetap mengembalikan nilai. FUNGSI print garis("*".3 Memanggil Dirinya Rekursif adalah istilah untuk fungsi yang memanggil dirinya sendiri.

Namun jika algoritma menjadi terlalu rumit silahkan terapkan rekursif. program: kalau Anda mencoba menambahkan baris berikut pada akhir . 9. KEPEMILIKAN VARIABEL 89 Rekursif memang membuat algoritma menjadi lebih pendek.update( {h:jml} ) return huruf nama = raw_input("Nama Anda: ") print hurufDalamNama() Variabel nama dibuat pada blok utama. Jadi sebisa mungkin tetap gunakan perulangan.has_key(h): jml = huruf[h] + 1 else: jml = 1 huruf. nal variabel yang dibuat di dalam fungsi tersebut. namun dapat dikenal Namun blok utama tidak dapat mengeSehingga oleh fungsi di atas. def hurufDalamNama(): huruf = {} for h in nama: if huruf.4 Kepemilikan Variabel Fungsi dapat mengenal variabel yang dibuat pada blok utama.4.9. Sedangkan tidak sebaliknya. Namun perlu diingat teknik ini tergolong lebih boros memori.

FUNGSI print huruf akan tampil pesan kesalahan: Traceback (innermost last): File "kepemilikan. line 13. Petunjuk Gunakan keys() dan sort(). .90 BAB 9.py". Tampilkan isinya seperti contoh berikut: Nama Anda: sugiana a = 2 g = 1 i = 1 n = 1 s = 1 u = 1 tanpa perlu mengubah fungsinya. in ? print huruf NameError: huruf Sehingga dikatakan kalau huruf dimiliki oleh fungsi hurufDalamNama(). Latihan hurufDalamNama() adalah fungsi yang mengembalikan dictionary sebagai keluarannya.

> > > exec("a = 5") >>> a 5 Berikut ini program kalkulator yang akan berhenti bila hanya tombol Enter saja yang ditekan. x = 8*3 24 x = 7+3 10 x = sin(45) .exec() exec() adalah fungsi interpreter yang akan menerjemahkan string sebagai perintah Python. memudahkan penggunaan fungsi tambahan. from math import * while 1: r = raw_input("x = ") if r == "": break exec("x = " + r) print x Anda dapat menuliskan rumus matematika sesuai dengan ketentuan Python.5.9. FUNGSI INTERPRETER .5 Fungsi Interpreter . Bahkan modul math sudah disertakan.EXEC() 91 9.

850903524534 x = pi*(10**2) 314.92 BAB 9.159265359 x = . FUNGSI 0.

Pembuatan le pada pemrograman aplikasi database biasanya untuk mencetak laporan dimana le tersebut berfungsi ganda: sebagai ke printer. 93 ."w") 1 Preview atau pracetak.1 Baca Tulis Untuk membuat atau membuka suatu le dapat menggunakan fungsi open(). f = open("test.txt". istilah untuk melihat hasil yang akan dicetak. preview 1 (ke layar) dan juga untuk pencetakan 10.Bab 10 File Bab ini membahas beberapa hal mengenai operasi le dan direktori.

2 Oleh karena itu untuk melakukan pencetakan langsung ke printer dapat memanfaatkan fungsi open() ini.close() 2 DOS menyebutnya sebagai LPT1 .write("coba") f. FILE f. String ini diakhiri karakter Enter.readlines(): print baris. namun belum tentu untuk string pada baris terakhir.close() readlines() mengembalikan list dimana elemennya merupakan string yang mewakili setiap baris le.2 Printer Sebuah device printer dapat dianggap sebuah le. f = open("/dev/lp0".write("test\n") f. print diberi tambahan koma agar tidak terjadi 10."w") f. f.94 BAB 10."r") for baris in f. /etc/hosts.close() Option w (write ) dipakai untuk menulis ke le. Contoh berikut f = open("/etc/hosts". biasanya ada di /dev/lp0. Oleh karena itu pencetakan karakter enter ("\n") sebanyak dua kali. sedangkan untuk membacanya gunakan option akan menampilkan isi le r (read ).

2. PRINTER Jangan lupa.write( chr(15) ) f. Atau bila Anda orangnya jalankan perintah berikut: $ su -c "chmod 666 /dev/lp0" Bila printer belum siap maka program akan terhenti pada hingga printer siap atau Ctrl-C ditekan. Kalau belum hubungi root). pastikan printer siap ( 95 ready ) sebelum program di system administrator (user atas dijalankan.1 Ukuran Huruf Sertakan chr(15) pada awal pencetakan untuk memperkecil Selama ukuran huruf."w") f. juga pastikan Anda memiliki hak tulis pada /dev/lp0 ini.2. perintah pengecilan masih tersimpan dalam memori printer. close() 10.10. f = open("/dev/lp0". . printer belum dimatikan maka perintah pengecilan masih berlaku. Jadi bila $ cat /etc/hosts > /dev/lp0 dijalankan maka pencetakan sudah menggunakan font yang kecil.close() Setelah program di atas selesai dijalankan. dan ini cukup digunakan sekali saja.

ord("P") Anda juga bisa mencari tahu sebenarnya ASCII-nya berapa: "\n" dan "\f" nomor print chr("\n"). Untuk kertas continues mengganti halaman beGunakan karakter rarti menuju ke lembar berikutnya. "\f" f = open("/dev/lp0". ord("\f") 10.write( "\f" ) f. Contoh: ord() print chr(80). karakter nomor 15 perlu dikirimkan ke printer terlebih dahulu. sedangkan fungsi sebaliknya. Namun untuk mengecilkan ukuran huruf. Program kecil berikut akan menggabungkan fungsi keduanya: . FILE 10.96 BAB 10."w") f.2.close() Karakter ASCII chr () sebenarnya fungsi untuk mendapatkan karakter ASCII berdasarkan nomor yang dimasukkan.2 Ganti Halaman Mengganti halaman bisa juga diartikan mengeluarkan kertas dari printer.2.3 Mencetak File Dengan perintah cat di atas kita sudah dapat mencetak le. digunakan untuk tujuan tersebut.

Perhatikan karakter gilnya sudah selesai.system( perintah ) Simpan program di atas dengan nama dengan cara berikut: cetak. 3 yang dapat menyebabkan program terhenti dan menunggu printer & yang menyebabkan penc- etakan tetap dilakukan meski program Python yang memang- 3 Misalnya: kertas habis (out of paper) . lalu cobalah $ python cetak.py /etc/hosts Bila melihat contoh sebelumnya. pencetakan le sebenarnya bisa sepenuhnya dilakukan dengan fungsi-fungsi pada Python.2.py. printer) os.10. PRINTER import sys import os namafile = sys."w") f.close() 97 perintah = "cat %s > %s &" % (namafile.write( chr(15) ) f. Cara di atas dilakukan untuk mengantisipasi kegagalan printer siap kembali.argv[1] printer = "/dev/lp0" f = open(printer. tanpa menggunakan program eksternal seperti cat.

sehingga ['cetak.chdir("/tmp") print os.3 Direktori Aktif Current directory jalankan. itu berisi Sedangkan list argv pada contoh di atas berisi parameter pada baris perintah (di console).98 BAB 10. tentu.txt".txt atau direktori aktif pada saat program dipada baris ini f = open("test.py'. Fungsi system() digunakan untuk menjalankan 10. cobalah program berikut: Untuk mengetahui direktori apa yang sedang aktif atau bagaimana pindah ke direktori ter- import os os. argv Modul os Modul ini memiliki banyak fungsi yang berkaitan dengan sistem operasi. FILE sys adalah hal-hal yang berkaitan sekali Modul sys Ruang lingkup modul dengan interpreter. program lain.getcwd() ."w") akan ditulis pada direktori aktif. Jadi le test. '/etc/hosts'].

Bab 11 Menangani Kesalahan Exception Suatu kesalahan dapat dijumpai dalam penulisan program dimana bisa kita kelompokkan menjadi dua: 1. syntax 2. Yang pertama sangat mudah ditemui karena Python terlebih dahulu memeriksa kebenaran penulisan sintaks sebelum menjalankan program. seperti contoh berikut: while 1 99 . Kesalahan logika atau exception. Kesalahan penulisan sintaks yang disebut sebagai error.

"bukan angka" Blok di dalam han maka blok try akan diawasi hingga apabila terjadi kesalaexcept dijalankan.py". MENANGANI KESALAHAN . Misalnya perintah berikut ini: 1 / 0 yang akan menimbulkan pesan kesalahan: ZeroDivisionError: integer division or modulo Perhatikan contoh berikut untuk menangkap suatu kesalahan: n = raw_input("Mencari akar n.5 except: print n.100 BAB 11. line 1 while 1 ^ SyntaxError: invalid syntax Sedangkan na exception terjadi pada saat program dijalankan karekesalahan logika. n = ") try: print float(n) ** 0.EXCEPTION print "sip" dimana akan muncul pesan kesalahan karena titik dua (:) belum disertakan dalam while: File "pesan. .

namun banyak hal baru yang juga dibahas seputar tipe data lainnya. 12.1 Membuat Nomor Baris Bila Anda penulis buku tentang bahasa pemrograman tentu sering memberikan contoh-contoh program yang jumlah barisnya bisa mencapai ratusan.Bab 12 Proyek String Paket Python menyertakan modul string yang memiliki berbagai fungsi untuk penanganan string. Dengan memberikan nomor baris paOleh karena itu Anda perlu da contoh tersebut tentu memudahkan mereka yang hendak menulis ulang pada komputer. Meski pokok bahasannya pengolahan string. membuat program kecil untuk kebutuhan tersebut dengan con101 .

zfill(n. baris).py ------------01| import sys 02| import string 03| 04| namafile = sys.readlines()) 10| lebar = len(str(jumlahbaris)) 11| file. 17| file. PROYEK STRING toh hasil sebagai berikut: nomorbaris.argv[1] 05| print namafile 06| print "-" * len(namafile) 07| 08| file = open(namafile. 12.102 BAB 12."r") 09| jumlahbaris = len(file. lebar) 16| print "%s| %s" % (nomor.1 Awali Dengan Nol .1.zfill() Fungsi zfill() akan memenuhi suatu angka atau string dengan huruf 0 (nol) di awalnya.readlines(): 14| n = n + 1 15| nomor = string. .close() Tentu saja Anda sudah tahu bagaimana isi programnya.seek(0) 12| n = 0 13| for baris in file.

6500 7.2 Penunjuk Pada File .Mangga.1.15000 2. Oleh karena itu kita akan konversi dokumen tersebut ke dalam suatu le teks dimana setiap eld dipisahkan dengan karakter titk koma (.Rambutan.12. FILE SEBAGAI TABEL 103 12.5000 4.seek() readlines() menyebabkan penunjuk (pointer ) paf berada di akhir le. .2.4750 6.Jambu. 12.Pisang.Harga 1.2000 1 Sehingga bisa disebut sebagai karakter pemisah. Contoh isinya sebagai berikut: Nomor.Nama Barang. 1 File ini biasanya disebut berformat Text CSV. Masalah yang dimaksud adalah bahwa dotmatrix memiliki kecepatan yang rendah bila mencetak dalam modus gras ketimbang mencetak dalam modus teks. Dengan fungsi seek() Pemanggilan da objek le penunjuk tersebut dapat dialihkan ke posisi pertama lagi.Duren.).Pepaya. Sehingga pemanggilan keduakalinya hanya menghasilkan list hampa.Jeruk.5500 5.7000 3.2 File Sebagai Tabel Bagi Anda yang pernah membuat dokumen dalam spreadsheet mungkin pernah mengalami masalah dalam mencetak dokumen dengan printer dotmatrix.

Contoh hasilnya adalah sebagai berikut: berapa jumlah karakter maksi- $ python csv.Belimbing.2000 10. PROYEK STRING 8.4000 Selanjutnya le ini dibaca.104 BAB 12. dan setiap kolom dipisahkan oleh karakter pemisah. 3.csv Nomor 1 2 3 4 5 6 Nama Barang Duren Jeruk Rambutan Mangga Pisang Jambu Harga 15000 7000 5000 5500 4750 6500 . dengan algoritmanya adalah sebagai berikut: 1. File dibuka dan diasumsikan sebagai sebuah tabel dimana setiap baris (record) dipisahkan dengan karakter enter. 2. Kemudian setiap nilai dicetak ke layar yang akan dipaskan jumlah karakternya dengan karakter spasi hingga mencapai jumlah maksimum.1500 9. diolah. tergantung posisi kolom elemen data tersebut.py barang.Bengkuang. lalu dicetak. Setiap kolom dianalisa: mumnya.Nanas.

splitfields(baris."r") 07| maks = {} 08| for baris in file.py -----01| import string 02| import sys 03| 04| namafile = sys.seek(0) 18| for baris in file.2.has_key(kolom) or \ 15| panjang > maks[kolom]: 16| maks. pemisah) 10| kolom = -1 11| for nilai in record: 12| kolom = kolom + 1 13| panjang = len(nilai) 14| if not maks.readlines(): 19| record = string." 06| file = open(namafile. csv.12.splitfields(baris.readlines(): 09| record = string. FILE SEBAGAI TABEL 7 8 9 10 Pepaya Nanas Bengkuang Belimbing 2000 1500 2000 4000 105 csv. pemisah) . sedangkan buah.update( {kolom:panjang} ) 17| file.py adalah program yang akan kita buat.csv adalah le hasil konversi dari aplikasi spreadsheet.argv[1] 05| pemisah = ".

1 Membelah String .close() Pemisah antar eld bisa saja menggunakan karakter lain.strip(nilai) 24| print string. spasi (" ") . dsb.2.ljust() & rjust() ljust() merupakan fungsi rata kiri yang akan memenuhi suUntuk atu string dengan karakter spasi di sebelah kanannya. Untuk menghapus sisi kirinya saja gunakan atau sisi kanannya saja dengan rstrip(). Asalkan bisa dipastikan nilai di dalam eld tidak mengandung karakter tersebut.splitfields() splitfields() merupakan fungsi untuk memecah suatu string menjadi list.106 BAB 12.strip() strip() akan menghapus karakter yang tidak kelihatan seperti enter ("\n") .2.2 Hapus Karakter Tak Tampak . lstrip().2. tab ("\t") .) misalnya. dimana posisi karakter tersebut berada di paling kiri dan paling kanan suatu string. 25| print 26| file. 12. titik koma (. PROYEK STRING 20| kolom = -1 21| for nilai in record: 22| kolom = kolom + 1 23| s = string. Fungsi ini membutuhkan string pemisah untuk melakukan pemecahan. 12. .ljust( s.3 Rata Kiri dan Kanan . maks[kolom] ). 12.

FILE SEBAGAI TABEL hal sebaliknya gunakan fungsi 107 rjust().2. Latihan Tampilkanlah angka dalam bentuk rata kanan dan terdapat pemisah ribuan.has_key() maks adalah variabel dictionary.12. Gunakan angka atau bukan. 12. dimana fungsi has_key() di- pakai untuk mengetahui apakah suatu kunci terdapat pada dictionary tersebut.4 Kunci Pada Dictionary . try untuk mengetahui .2.

PROYEK STRING .108 BAB 12.

Bagian III Qt 109 .

.

Qt juga mendukung penggunaan database server untuk menyimpan data. Sebagai referensi tambahan. fungsi.sebuah window manager terkemuka di lingkungan Linux.trolltech. Oleh karena itu library ini sangat cocok dalam pembuatan aplikasi bisnis. 4 radiobox. untuk membuat aplikasi console bi- asa. 1 www. dsb. grid . 3 Meski dengan Qt memungkinkan form (window).Bab 13 Pendahuluan Qt dibuat oleh Trolltech 1 dan merupakan library 2 untuk aplikasi 3 yang menggunakan form dimana di dalamnya terdapat button. konstanta. dsb. namun tujuan dibuatnya library ini memang untuk aplikasi berbasis 4 Grid: bentuk tabel 5 Class: tipe data objek 111 .com 2 Library: pustaka kumpulan class. Qt juga digunakan dalam KDE . Objek-objek tersebut tersedia dalam bentuk class 5 .

menarik.uk . Memungkinkannya penggunaan Qt pada Python diharapkan terbentuk aplikasi bisnis yang handal. serta memperkecil waktu pengembangan.co. 6 phil@riverbankcomputing.112 BAB 13. PENDAHULUAN PyQt dibuat oleh Phil Thompson 6 dan merupakan library Python untuk penggunaan Qt. mudah digunakan.

Kesederhanaannya ingin menunjukkan bagaimana membuat aplikasi Qt semudah mungkin. hello.__init__(self) 06| self.setCaption("Hello World !") 07| self.1.show() 08| 113 .Bab 14 Aplikasi Pertama Program pendek berikut akan menampilkan sebuah form seperti pada gambar 14.py -------01| from qt import * 02| 03| class FormHello(QWidget): 04| def __init__(self): 05| QWidget.

visual class ). Cukup sebuah QApplication setMainWidget().114 BAB 14. kemampuan. merupakan tipe data.1: Hello World ! 09| 10| 11| 12| app = QApplication([]) fm = FormHello() app. atau fasilitas. terutama seputar istilah-istilah yang Mirip dengan teknik pemrograman non-objek. APLIKASI PERTAMA Gambar 14.setMainWidget(fm) app.exec_loop() Form ini nantinya QWidget merupakan class untuk membuat form. . 2 Python. Dari kata: feature. 2 Fitur: ciri. Sedikit men- gulas tentang teknik ini. dalam suatu aplikasi yang akan menunjuk salah satu form sebagai form utama dengan fungsi 14. Sedangkan yang ada menjadi wadah bagi seluruh objek yang tampak ( QApplication merupakan pengatur keseluruhan form 1 dalam suatu aplikasi. sedangkan instance sering disebut objek saja. pakan class meruvariabel yang 1 Sebuah aplikasi biasanya memiliki form lebih dari satu.1 Berorientasi Objek Qt merupakan library yang menggunakan teknik pemrograman berorientasi objek ( object oriented programming disingkat OOP) yang memang menjadi salah satu tur digunakan.

dan ini merupakan standar Python. PROGRAM UTAMA ( 115 inheritence ) Pada contoh di atas. keyboard. masih bisa diterapkan. mouse. Secara umum manfaat dari teknik pemrograman berorientasi objek adalah menyederhanakan pembuatan program pada aplikasi yang komplek (rumit) melalui proses penurunan sifat ini. Tapi bila kompleksitas program sudah sedemikian besar seperti menyangkut pengaturan tampilan. class dari class pakan pembentuk ( constructor ) FormHello merupakan keturunan QWidget. Fungsi __init__() meruyang akan dijalankan ketika pertama kali suatu objek diciptakan. dsb. yang berarti pula objek fm dimuat di memori sekaligus ditampilkan di layar monitor melalui show().2 Program Utama Program utamanya sendiri dimulai saat penciptaan objek yang ber-class app QApplication. perubahan suatu sifat dapat dilakukan melalui Untuk algoritma yang sederhana hal ini parameter dalam suatu fungsi. Namun class dengan memberi kalimat FormHello melakukan perubahan sifat "Hello World !". . 3 14. Selanjutnya objek app selaku form manager menentukan form mana yang merupakan form utama.14. Pemanggilan fungsi buah untuk menciptakan bentuk asli leluhur yang memang berupa se- QWidget. maka penerapan fungsi saja akan membuat program menjadi sangat besar dan pada akhirnya lebih menyulitkan pada saat penelusuran kesalahan (debugging). Tanpa penentuan ini aplikasi 3 Pada teknik non objek. diikuti dengan penciptaan objek fm yang ber-class FormHello dimana __init__() mulai dijalankan.2.__init__() berguna form .

form tidak ditampilkan namun program tetap ber- self. Coba saja Anda hapus dan jalankan kembali program tersebut. 14. berguna untuk menampilkannya. Setiap fungsi yang didenisikan di dalam class setidaknya memiliki sebuah parameter yang mewakili class tersebut.show() exec_loop() dijalankan. Kata sebenarnya bisa diganti dengan kata lainnya. Hal ini dimungkinkan karena tikan perulangan ( up.4 Fungsi Pada Objek self. self memang merupakan perjanjian antar programmer saja yang 14. Jadi di dalam exec_loop() memang terdapat semacam while yang akan terus dijalankan hingga form utama ditutup. APLIKASI PERTAMA looping ) exec_loop() memang akan menghenmanakala form utama sudah ditut- tidak akan berhenti walaupun semua form sudah ditutup. Anda kesulitan menghentikannya (tampak perintah ini di console yang lain: hang ) Kalau lakukan saja 4 Caption: judul form .show() caption4 di suatu form.3 self self sebagai parameter masukan __init__() mewakili FormHello. Tanpa ini.setCaption() Sedangkan jalan karena berarti objek ber-class but menggunakan fungsi FormRelasi tersesetCaption() yang berasal dari leluhurnya. Fungsi ini memberikan nilai pada self.116 BAB 14.

4.exec_loop() .py --------01| from qt import * 02| 03| class FormHello(QWidget): 04| def __init__(self): 05| QWidget.__init__(self) 06| self.show() 11| app.setMainWidget(fm) 12| app.setCaption("Hello World !") 07| 08| app = QApplication([]) 09| fm = FormHello() 10| fm. FUNGSI PADA OBJEK $ killall python 117 show() dan setCaption() dipanggil pada saat penciptaan yang juga dapat dipanggil sesudahnya: hello1.14.

APLIKASI PERTAMA .118 BAB 14.

15.1 Buku Alamat Berikut ini form yang diniatkan untuk pengisian buku alamat. Buku ini juga menggunakan istilah yang sama untuk menyebut objek- QWidget dan keturunannya. memang class untuk membuat form. 119 . Anda akan diperkenalkan dengan berbagai class untuk mema- 1 Lihat kembali halaman 84 tentang istilah object & class. 1 leluhur semua objek- Dalam istilah Qt. form yang sederNamun sebenarnya ia merupakan tampak ( visual object ). yaitu widget.Bab 15 Visual Class QWidget hana. visual object disebut sebagai tampak.

editAlamat = QTextEdit(self) 17| self.editNama.20) 10| labelNama.150.10.65.40.160.setGeometry(90.editAlamat.__init__(self) 06| self.editNama = QLineEdit(self) 15| self.show() 22| 23| app = QApplication([]) 24| fm = FormRelasi() .102) 18| buttonSimpan = QPushButton(self) 19| buttonSimpan.setText("Nama") 11| labelAlamat = QLabel(self) 12| labelAlamat.resize(268. maupun unbutton ).setText("Simpan") 21| self.setGeometry(90. VISUAL CLASS editor ).65.40.setText("Alamat") 14| self.setGeometry(10.80.120 BAB 15.setGeometry(10.py ---------01| from qt import * 02| 03| class FormRelasi(QWidget): 04| def __init__(self): 05| QWidget. sukkan data ( tuk melaksanakan perintah tertentu ( relasi1.194) 07| self.24) 20| buttonSimpan.setGeometry(90.20) 16| self.10.160. menampilkan tulisan (label ).setCaption("Relasi") 08| labelNama = QLabel(self) 09| labelNama.20) 13| labelAlamat.

1.setMainWidget(fm) app. BUKU ALAMAT 25| 26| 27| 28| app. Sifatnya hingga pengguna ( sung. seuser ) tidak dapat berinteraksi langinput ) dari penggu- QLineEdit tempat menuliskan masukan ( Nama.editAlamat. Nanti dipakai untuk perintah menyimpan da- Sedangkan fungsi berikut ini selain dimiliki oleh keempat class tersebut. na. fm. multiline ).exec_loop() print "Nama". misalnya untuk QPushButton ta. tombol yang biasanya dipakai untuk perintah ter- tentu.text() 121 Class yang dimaksud adalah: QLabel untuk menampilkan tulisan. read-only . . fm.text() print "Alamat".15. QWidget juga terwarisi resize() mengubah ukuran form yang membutuhkan masukan berupa dua bilangan bulat yang mewakili panjang dan lebar form dalam satuan pixel. tetapi dengan kemampuan lebih dari satu baris masukan ( menampung Alamat.editNama. Pada contoh berikut dipakai untuk menampung QTextEdit mirip QLineEdit.

Berbeda dengan Alamat yang menggunakan QTextEdit yang sanggup lebih dari satu baris. bahkan dengan kemampuan berganti baris secara otomatis ( towarp ). Sedangkan dua angka berikutnya merupakan ukuran (besarnya) objek la- Pengisian Nama menggunakan class QLineEdit yang hanya mam- pu menampung masukan sebanyak satu baris saja. Seperti juga dan setText(). seperti halnya pada QLineEdit dan QTextEdit. text() dimiliki oleh objek lain yang memiliki tempat untuk tulisan. Dua angka pertama merupakan posisi yang ditentukan dari sudut kiri atas form. QLabel . VISUAL CLASS Gambar 15. seperti QPushButton.122 BAB 15. au- setText() pada QLabel dan QPushButton merupakan fungsi untuk mengisikan teks. Pencetakan Nama dan Alamat pada akhir program ingin menunjukkan bagaimana mendapatkan nilai yang sudah dimasukkan pemakai. karena memang kebutuhannya seperti itu.1: Form Alamat setGeometry() menentukan posisi dan ukuran widget. Fungsi yang sama juga terdapat pada objek lain yang memiliki tempat untuk tulisan. bel tersebut.

Parent merupakan sebagai child .. Jadi. labelAlamat.1.editNama = .2 Parent dan Owner Pembuatan di depannya. Pada wadah 2 objek. Atau dikatakan FormRelasi sebagai pemilik (owner ) keduanya. dan tombolSimpan bukan milik class FormRelasi tetapi milik fungsi __init__(). Sedangkan labelNama. Ini artinya class editNama dan editAlamat menggunakan kata self FormRelasi memiliki dua objek tersebut.1. berarti variabel dimiliki sedangkan. Sehingga bisa saja suatu objek dimiliki objek A namun berwadah objek B. . Objek inilah yang disebut dikatakan bahwa baris: labelNama berwadah FormRelasi.. BUKU ALAMAT 123 15.3 namun tetap ber-wadah pada FormRelasi... = QLineEdit(self) berarti QLineEdit tersebut berwadah pada self. editNama self. QLabel yang baru dibuat 15. contoh di atas Perhatikan labelNama = QLabel(self) dimana self merupakan wadah bagi dengan nama variabel labelNama. Kepemilikan Variabel pada Bab Fungsi .1.15. 2 Lihat 3 Lihat pembahasan mengenai wadah di halaman 123.1 Parent dan Child Kembali membahas istilah. self. meski hal ini jarang diterapkan.

VISUAL CLASS 15. . 4 Segmentation fault: kesalahan program yang sering disebabkan masalah manajemen memori.1.124 BAB 15. self yang ditulis gunakan pedoman berikut ini: Gunakan awalan nya. namun ada beberapa yang bisa menyebabkan segmentation fault.1.4 Modul qt Modul qt berisi banyak class dan fungsi yang sering dipakai pada contoh-contoh program berikutnya.3 Dengan Atau Tanpa self Bagaimana kita menentukan suatu objek dimiliki oleh class atau cukup dimiliki oleh fungsi didalamnya ? Kalau mengambil jalan aman sebaiknya semua dimiliki oleh class (dengan awalan Namun kalau Anda merasa repot karena terlalu banyak kata self). Kesalahan ini cukup fatal karena tidak terdeteksi oleh programnya itu sendiri.4 15. self apabila objek tersebut akan dipakai oleh blok lain diluar fungsi yang membuat- Kebanyakan objek bisa diterapkan dengan pedoman di atas. Oleh karena itu kita hindari penulisan import qt dan sebagai gantinya gunakan from qt import * agar tidak perlu menyebutkan nama modul didepan class yang digunakan.

text() atau bisa juga dengan s = "Nama " + str(self. BUKU ALAMAT 125 15. dan tergolong sebagai non-visual class5 . misal- s = "Nama " + self.setText( QString("Nuryadi") ) sama hasilnya dengan: self. dsb.15.editNama. gai properti objek seperti parameter masukan caption().editNama.setText( "Nuryadi" ) dimana editor bertipe QLineEdit.1. misalnya.text() karena ini merupakan kesalahan dimana tipe string ditambahkan dengan string: QString. text(). Juga sebagai setCaption().1.editNama. dst.text()) 5 Non-visual class: bukan keturunan QWidget. Untuk mengatasinya gunakan proses format s = "Nama %s" % self. Namun jangan harapkan hal yang sama ketika kita ingin mengolah nya penggunaan operator tambah (+) seperti: text() de- ngan perintah standar Python lainnya mengenai string.5 String Atau QString QString digunakan untuk penanganan string.editNama. . setText().editNama. Objek ini banyak terdapat pada berba- Kita bisa menuliskan baris berikut: self.

Logikanya penyimpanan data dilakukan pada saat tombol tersebut di-klik. . event. print sudah 15.126 BAB 15. maka data disimpan dalam sebuah le bernama dengan bentuk sebagai berikut: relasi.txt NAMA: <nama> ALAMAT: <alamat> --File plaintext ini merupakan le yang bisa dibaca dengan text editor biasa. namun tombol Simpannya belum berfungsi.2 Sinyal FormRelasi bagai sudah dapat ditampilkan. tombol tersebut mengirimkan sinyal ( signal ). Karena sifat seperti fungsi str() maupun string formatting %. Berhubung sampai di sini belum dibahas tentang database. VISUAL CLASS s tetap bertipe string dan bukan Bila Anda menggunakan dan sampai di sini print untuk mencetak QString. QString maka hal ini tidak perlu dilakukan dimana penggabungan bisa dengan koma.6 Saat inilah yang disebut se- Pada saat kejadiannya (tombol di-klik). seperti contoh di atas. 6 Karena ap disebut proses tersebut maka pemrograman berorientasi objek kermemiliki tur event driven programming (pengendalian berdasarkan kejadian). Sinyal ini dapat diman- faatkan untuk menyisipkan fungsi penyimpanan data.

194) 08| self. SINYAL 127 relasi2.40.160.connect( buttonSimpan.10.150.65.setGeometry(90.setText("Nama") 12| labelAlamat = QLabel(self) 13| labelAlamat.setText("Simpan") 22| self.160.__init__(self) 07| self.editAlamat = QTextEdit(self) 18| self.editAlamat.py ---------01| from qt import * 02| import os 03| 04| class FormRelasi(QWidget): 05| def __init__(self): 06| QWidget.show() 23| self.2.20) 11| labelNama.tombolKlik ) 25| 26| def tombolKlik(self): 27| rec = "NAMA: %s\nALAMAT:\n%s\n---\n" % \ .20) 17| self.10.setGeometry(10.setText("Alamat") 15| self.setCaption("Relasi") 09| labelNama = QLabel(self) 10| labelNama.setGeometry(90. 24| SIGNAL("clicked()").40.102) 19| buttonSimpan = QPushButton(self) 20| buttonSimpan.editNama = QLineEdit(self) 16| self.65. self.20) 14| labelAlamat.setGeometry(10.resize(268.setGeometry(90.24) 21| buttonSimpan.80.15.editNama.

system("touch " + file) os.rename(fileSementara. file) app = QApplication([]) fm = FormRelasi() app. berarti yang perlu dilakukan adalah mendenisikan suatu class baru yang merupakan turunan dari class objek yang Anda kehendaki.exec_loop() di atas menyatakan bahwa: Fungsi connect() Jalankan jalankan tombolKlik() pada saat buttonSimpan menclicked() ke dalam slot yang telah disediakan.read() + rec) fSementara.text()) file = "relasi.setMainWidget(fm) app.editNama.write(f. "w") fSementara. self.txt" fileSementara = "~" + file os. Karena proses itulah teknik ini disebut sebagai penyisipan fungsi Tanpa slot yang telah diberikan para pengembang Qt. .128 BAB 15.close() f.editAlamat.close() os.system("touch " + fileSementara) f = open(file.text(). maka Anda tidak dapat menyisipkan suatu fungsi ke dalam fungsi lain yang dimiliki suatu Jika itu terjadi. objek. VISUAL CLASS 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| 41| 42| 43| 44| (self."r") fSementara = open(fileSementara.

dan Petunjuk setFocus() Gunakan fungsi untuk memindahkan kursor pada objek yang dimaksud. clear() untuk mengosongkan. . Sedangkan touch yang dijalankan dengan fungsi system() merupakan perintah Linux yang berfungsi memeriksa keberadaan suatu le. 15. SINYAL leluhur semua class. baik yang tampak maupun tidak. Jika tidak ada ia akan membuatnya namun tidak berisi apa-apa. melainkan diikuti dengan pengosongan otomatis kursor sudah berada pada editNama dan editAlamat. Python memang dikatakan sebagai antarmuka bahasa C interface ).2. Tujuannya adalah memudahkan pengguna untuk mengisikan data berikutnya.1 Keterkaitan Dengan C++ Fungsi SIGNAL() pada program di atas merupakan penghubung 7 (C antara Python dengan library Qt yang dibangun dengan bahasa C++. 129 connect() sebenarnya milik class QObject yang merupakan Latihan Pada saat buttonSimpan di-klik bukan hanya perin- tah penyimpanan yang dijalankan.2. Modul os rename() adalah fungsi untuk mengubah atau memindahkan le. Namun C++ dapat mengenal dengan baik seluruh perintah C. lalu secara editNama. Hal ini bisa juga dikatakan library yang 7C dibangun sebelum C++.15.

Anda dapat menggunakan dokumentasi Qt yang ditulis untuk C++ sebagai acuan untuk mempelajari penggunaan Qt pada Python (baca: tentu. linecase. ulang atau dalam dokumentasi Qt disebut sebagai .py ----------01| from qt import * 02| 03| class LineCase(QLineEdit): 04| Normal = 0 8 Override:ditulis reimplementation . yaitu turunan yang akan memperbesar huruf. Contohnya adalah __init__() sifatnya yang QLineEdit Berikut ini contoh lain penggunaan sinyal. Tentunya Anda perlu menyesuaikannya dengan gaya bahasa Python pada bagian-bagian ter- 15.2.130 BAB 15.2 Sinyal atau Event Sinyal ( ngan suatu fungsi. override8 ) oleh turunan suatu objek. PytQt). signal ) berkaitan dengan suatu kejadian (event ) dalam objek dimana sinyal yang muncul kemudian dihubungkan deIstilah event dalam Qt sebenarnya juga berupa kejadian yang diwakili oleh suatu fungsi. Perbedaannya dengan sinyal adalah event merupakan fungsi yang bisa diganti ( terjadi pada saat suatu objek diciptakan. menawarkan kekayaan tur C dan C++. VISUAL CLASS Praktis Python ditulis untuk C dapat diakses oleh Python.

LineCase.setText( self.teksBerubah = None 14| self.berubah) 17| 18| def berubah(self. case=0): 09| QLineEdit.Normal and \ 21| self.teksBerubah( self ) 30| 31| if __name__ == "__main__": 32| app = QApplication([]) 33| fm = LineCase(None.15._OnSet: return 20| if self.__init__(self.case == self._panjang < t.connect( self.teksBerubah: self. parent) 10| self._panjang = 0 13| self._OnSet = 0 12| self.text().Upper) . t): 19| if self.2._OnSet = 0 28| self. parent.length() 29| if self._panjang = t. SINYAL 131 05| Upper = 1 06| Lower = 2 07| 08| def __init__(self.Upper: 24| self.text()._OnSet = 1 23| if self.case = case 11| self.case != self.setText( self.lower() ) 27| self. 16| self.upper() ) 25| else: 26| self.length(): 22| self. 15| SIGNAL( "textChanged( const QString& )" ).

VISUAL CLASS 34| 35| 36| fm.teksBerubah: self. Cara ini me- dimana baris if self.132 BAB 15.3 Membuat Event Sinyal textChanged() pada LineCase sudah digunakan. Hal ini dimungkinkan karena blok utama program akan memeriksa terlebih dahulu apakah ia merupakan program utama atau sebagai modul (lihat __name__) 15.py dapat dijalankan sebagai modul maupun program utama. pada- hal Anda ingin menyisipkan fungsi lain pada saat teks berubah.setMainWidget(fm) app. Cara ini sudah dicontohkan oleh __init__(). dikarenakan ia dipanggil dengan sebuah parameter di dalamnya. Perhatikan bagian . Sedangkan cara kedua adalah dengan menyiapkan menjalankannya di dalam fungsi mang telah diterapkan event teksBerubah LineCase. yaitu dengan adanya variabel berubah() variabel event dan (kalau ada) tadi.show() app. Cara pertama bisa dengan menulisulang ( reimplementation ) LineCase menjadi class baru dan mengubah source fungsi berubah(). maka penggantinya harus berupa event dengan sebuah parameter masukan.2.exec_loop() linecase.teksBerubah( self ) menunjukkan bahwa variabel event teksBerubah akan diperiksa apakah nilainya sudah diganti dengan yang lain. Jika ya.

15.2. SINYAL
self.teksBerubah( self )
Lebih jelasnya jalankan contoh berikut ini:

133

linecase1.py -----------01| from qt import * 02| from linecase import LineCase 03| 04| class FormCase(QWidget): 05| def __init__(self): 06| QWidget.__init__(self) 07| self.line = LineCase(self, LineCase.Lower) 08| self.line.teksBerubah = self.ubahCaption 09| self.show() 10| 11| def ubahCaption(self, w): 12| self.setCaption( w.text() ) 13| 14| app = QApplication([]) 15| fm = FormCase() 16| app.setMainWidget(fm) 17| app.exec_loop() self9 yang jumlahnya sebanyak yang ditetapkan variabel event teksBerubah pada LineCase. Contoh di atas menunjukkan parameter tersebut bertipe LineCase, sehingga fungsi text() bisa digunakan. ubahCaption()
harus memiliki parameter selain

9 Ingat,

self harus disertakan dalam setiap fungsi di dalam class.

Bila

fungsi didenisikan di luar class, maka - tentu - self tidak perlu disertakan.

134

BAB 15. VISUAL CLASS
Pahami benar-benar tentang event ini, karena pada contoh-contoh selanjutnya dimanfaatkan seoptimal mungkin untuk meminimalkan kode program

15.3 Hiasan
Terlepas dari alur suatu sistem, ada baiknya kita mengetahui beberapa hal untuk memperbagus tampilan dengan tujuan aplikasi yang digunakan bisa lebih informatif.

15.3.1 Font - QFont
Font (QFont) merupakan atribut karakter, misalnya: Jenis Italic Underline Bold Arial, Helvetica, Courier

Miring
Garis bawah

Tebal
berikut akan menampilkan sebuah

font.py

bergantung dari hasil masukan dari

QLabel QLineEdit.

yang isinya

font.py ------01| from qt import * 02| 03| class FormFont(QWidget):

15.3. HIASAN
04| 05| 06| 07| 08| 09| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29|

135

def __init__(self): QWidget.__init__(self) self.setCaption("Font") self.label = QLabel(self) self.label.setAutoResize(1) self.label.setText( "Tulis saja" ) font = QFont(self.label.font()) font.setFamily("Courier [Adobe]") font.setPointSize(48) font.setBold(1) font.setItalic(1) font.setUnderline(1) self.label.setFont(font) self.teks = QLineEdit(self) self.teks.setGeometry( 10, 80, 106, 20 ) self.show() self.connect( self.teks, SIGNAL( "textChanged( \ const QString&)"), self.ubahLabel) def ubahLabel(self, teks): self.label.setText( teks ) app = QApplication([]) fm = FormFont() app.setMainWidget(fm) app.exec_loop() setFont() merupakan milik QWidget yang otomaQLabel di

Pada dasarnya

tis dapat digunakan juga oleh keturunannya seperti

136

BAB 15. VISUAL CLASS
Penjelasan mengenai fungsi pada

atas.

QFont

di atas adalah:

font()

mengembalikan QFont, berisi informasi font suatu widget.

setFamily()

menentukan jenis font. Nama font yang tercan-

tum berdasarkan font yang terpasang pada sistem. Untuk mengetahuinya bisa dengan menu

Settings | Congure Editor | Fonts.

kwrite.

Pilih

setPointSize()

menentukan ukuran. Angka di dalamnya ju-

ga perlu disesuaikan dengan yang terdaftar, tergantung dari jenisnya.

setBold()

menentukan apakah font akan ditebalkan. Nilai masukannya hanyalah

boolean

(logika) 1 (ditebalkan)

atau 0 (tidak ditebalkan).

setItalic()

memiringkan font. Nilai masukannya juga boolean. pemberian garis bawah. Nilai masukannya ju-

setUnderline()

ga boolean. Di luar masalah font, program di atas cukup menarik karena melibatkan ran

setAutoResize() yang menentukan apakah ukuQLabel akan mengikuti panjang tulisan. Serta penggunaan sinyal textChanged() yang terpicu saat teks pada QLineEdit
berubah.

15.3. HIASAN

137

15.3.2 Warna - QColor
black, white, darkGray, gray, lightGray, red, green, blue, cyan, magenta, yellow, darkRed, darkGreen, darkBlue, darkCyan, darkMagenta, dan darkYellow. warna.py berikut melanjutkan font.py, dengan warna label
nama warna yang siap pakai, yaitu: yang telah diubah.

QColor merupakan class warna

yang telah menyediakan nama-

warna.py -------01| from qt import * 02| 03| class FormWarna(QWidget): 04| def __init__(self): 05| QWidget.__init__(self) 06| self.setCaption("Warna") 07| self.label = QLabel(self) 08| self.label.setAutoResize(1) 09| self.label.setPaletteForegroundColor( 10| QColor("yellow")) 11| self.label.setPaletteBackgroundColor( 12| QColor("blue")) 13| self.label.setText( "Tulis saja" ) 14| self.teks = QLineEdit(self) 15| self.teks.setGeometry( 10, 20, 106, 20 ) 16| self.show() 17| self.connect( self.teks, SIGNAL( "textChanged( \ 18| const QString&)"), self.ubahLabel)

138

BAB 15. VISUAL CLASS
19| 20| 21| 22| 23| 24| 25| 26| def ubahLabel(self, teks): self.label.setText( teks ) app = QApplication([]) fm = FormWarna() app.setMainWidget(fm) app.exec_loop()

setPaletteForegroundColor() menentukan warna pada latar depan objek, sedangkan setPaletteBackgroundColor() pada latar belakangnya. Keduanya dimiliki QWidget. QColor juga dapat menerima masukan berupa tiga bilangan
bulat dengan nilai antara 0 hingga 255 yang mewakili komponen inti warna: merah (

red ),

hijau (

green ),

dan biru (

blue )

atau

sering disebut sebagai RGB. Sehingga perintah seperti ini:

setPaletteForegroundColor(QColor("white"))
bisa juga ditulis demikian:

setPaletteForegroundColor(QColor(255,255,255))

15.3.3 Parent Berpengaruh
Font dan warna pada parent bisa mempengaruhi objek lain yang menjadi child-nya. Cobalah mengubah warna ngan mengganti

FormWarna:

de-

15.4. YA ATAU TIDAK - QCHECKBOX
Gambar 15.2: Checkbox

139

self.label.setPaletteBackgroundColor(QColor("blue"))
menjadi

self.setPaletteBackgroundColor(QColor("blue"))

15.4 Ya Atau Tidak - QCheckBox
Checkbox (QCheckBox) merupakan objek yang dapat menerima
masukan seperti 1. Bersifat

QLineEdit

dengan sifat khas berikut:

toggle (ya atau tidak) checked (benar).

2. Memiliki sebuah kotak isian yang apabila di-klik bermakna ya, dan bila di-klik sekali lagi berarti tidak. Keduanya dibedakan dengan sebuah tanda

3. Memiliki label sebagai keterangan dari kotak isian tersebut.

checkbox.py menunjukkan bagaimana QCheckBox dapat digunakan untuk mengubah warna form.

setPaletteBackgroundColor(self.checkBox.exec_loop() isChecked() mengembalikan boolean dimana 1 berarti ya.255)) 18| else: 19| self.py ----------01| from qt import * 02| 03| class FormCheckBox(QWidget): 04| def __init__(self): 05| QWidget.putihkan ) 11| self. VISUAL CLASS checkbox.140 BAB 15.checkBox.255.connect( self.warnaAsli) 20| 21| app = QApplication([]) 22| fm = FormCheckBox() 23| app.checkBox = QCheckBox( self ) 08| self.setPaletteBackgroundColor(QColor( 17| 255.setCaption("Check Box") 07| self.setMainWidget(fm) 24| app.warnaAsli = self. .isChecked(): 16| self.setText( "Putihkan" ) 09| self.checkBox. 10| self.paletteBackgroundColor() 12| self. SIGNAL( "clicked()").__init__(self) 06| self.show() 13| 14| def putihkan(self): 15| if self.

2. suatu proses akan dilakukan secara otomatis atau tidak. na- mun hanya satu saja yang bisa dipilih. . 3.5. Dalam sistem kepegawaian. 2. PILIH SALAH SATU . seorang pegawai diikutsertakan dalam asuransi kesehatan atau tidak. Contoh berikut berisi daftar golongan darah yang bisa dipilih dimana hal yang ingin diungkapkan adalah: 1. Pada sistem KTP (Kartu Tanda Penduduk).5 Pilih Salah Satu .15. terdapat beberapa pilihan.QRADIOBUTTON Pada sebuah form isian dalam suatu aplikasi. seseorang merupakan WNI (Warga Negara Indonesia) atau WNA (Warga Negara Asing). 15. Dalam sebuah form pengaturan ( setting ).QRadioButton Radiobutton (QRadioButton) merupakan objek-pilihan yang lazimnya terdiri dari beberapa objek yang tergabung dalam Meski di dalam QButtonGroup QButtonGroup. Membatalkan pilihan ( reset ). dapat dimanfaatkan untuk beberapa contoh berikut ini: 141 QCheckBox 1. Sebagai pedomanpraktis: Gunakan checkbox apabila hanya ada dua pilihan. Bagaimana mengetahui pilihan.

golA = QRadioButton( self.golDarah.golB = QRadioButton( self.btReset.golB.py --------------01| from qt import * 02| 03| class FormRadioButton(QWidget): 04| def __init__(self): 05| QWidget.setGeometry( 5. 60.golDarah.setGeometry( 20.setText( "A" ) 13| self. 40.setTitle( "Gol.setPaletteBackgroundColor( 10| QColor( "green" ) ) 11| self.golA. 20 ) 23| self. Darah" ) 08| self. 100. 20 ) 17| self.142 BAB 15.golB.setCaption( "Ada %d golongan darah" % 24| self.golB.setGeometry( 5.golDarah.golB = QRadioButton( self.golB.count() ) 25| self.setText( "O" ) 22| self. 50.golB. 20. 80.setText( "B" ) 16| self.golDarah ) 21| self. 150 ) .setGeometry( 5.golDarah ) 15| self. 20 ) 20| self.golA.setText( "Reset" ) 27| self.__init__(self) 06| self.setGeometry( 5. 20.setText( "AB" ) 19| self.golB = QRadioButton( self.btReset = QPushButton( self ) 26| self. 50. VISUAL CLASS radiobutton1.golDarah ) 12| self. 50.golDarah. 20 ) 14| self.btReset.golDarah = QButtonGroup( self ) 07| self. 50.golDarah ) 18| self.golB.move( 5. 120 ) 09| self.

setMainWidget(fm) app.btResetKlik ) def golDarahKlik(self.text().15.5. SIGNAL("clicked(int)"). SIGNAL("clicked()"). ia mengembalikan None10 .golDarah. belum ada. PILIH SALAH SATU .QRADIOBUTTON 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| 41| 42| 43| 44| 45| 46| atas: 143 self. objek hampa .exec_loop() QButtonGroup di Berikut ini penjelasan fungsi dan sinyal pada selected() count() 10 None: mengembalikan radiobutton yang terpilih.golDarah.btReset.golDarahKlik ) self.connect( self.setChecked( 0 ) self.golDarah.find(index).golDarah. index): self.setCaption( "Tidak ada yang dipilih" ) app = QApplication([]) fm = FormRadioButton() app. self.setCaption( "Golongan %s (%d) dipilih" % ( self. index) ) def btResetKlik(self): if self.connect( self.selected(). Bila mendapatkan jumlah radiobutton dalam QButtonGroup.selected(): self. self.show() self.

dan O saja. QPushButton. Sinyal ini menyertakan nomor index radiobutton tersebut. ka Padahal mungkin . dimana nilai masukan 0 berarti tidak dipilih. sedangkan 1 berarti terpilih. Bila itu terjadi.py memiliki kelemahan dalam hal eksibili- tas. Kecuali setChecked() yang sebenarnya keturunan objek yang bersifat tombol seperti menentukan apakah radiobutton terpilih atau tidak.golX. QRadioButton QButton . yaitu: 1. AB. karena untuk menambah golongan darah harus mengubah source program yang cukup banyak. Anda juga bisa mengganti tombol Reset dengan sebuah pilihan baru pada radiobutton yang berisi Tidak tahu dimana pada saat pertama ditampilkan menjadi nilai default. 11 Meningkatkan Fleksibilitas Mayoritas kita mungkin hanya tahu bahwa golongan darah itu A.dan bisa jadi ada golongan darah lainnya di dunia ini. find() clicked() sinyal yang muncul saat radiobutton di-klik. Pada contoh di atas digunakan untuk me- reset QButtonGroup. 11 Default: nilai standar atau nilai pertama . Mendenisikan objek baru. misalnya self. VISUAL CLASS mendapatkan radiobutton pada nomor index tertentu. dan QRadioButton sendiri. B. QToolButton. ma- radiobutton1.144 BAB 15.leluhur semua QCheckBox. Fungsi seperti setText() dan text() berasal dari QButton.

dan sebagai gantinya radiobutton ditambah daftar baru yaitu Tidak tahu yang bermakna operator belum dapat mencatat golongan darah orang yang dimaksud. Berikut ini rencana perbaikannya: 1. nantinya. 2. .5. Pembuatan objek golongan darah menggunakan perulangan (looping). 3.QRADIOBUTTON Gambar 15. sehingga koordinatnya ditentukan dengan suatu rumusan.15. 3. Daftar golongan darah diletakkan dalam list (array).py --------------01| from qt import * 02| 12 Anggap saja radiobutton dalam program ini merupakan bagian dari suatu form pengisian identitas diri. Menentukan lebar radiobutton. karena bila daftar pilihan bertambah maka lebarnya pun juga harus bertambah.3: Radiobutton 145 2. Tombol Reset ditiadakan. Menentukan koordinat setiap objek dalam radiobutton. 12 Tidak tahu diletakkan di paling atas dan merupakan nilai default pada saat pertama kali program dijalankan. radiobutton2. PILIH SALAH SATU .

20. "B".setCaption( "Ada %d golongan darah" % 24| (self. 28| SIGNAL("clicked(int)"). "O"] 07| # layout 08| lebar = 20 09| jmlGol = len(daftarGol) 10| self.golDarah.setPaletteBackgroundColor( 15| QColor("green")) 16| i = 1 17| for gol in daftarGol: 18| rb = QRadioButton( self.connect( self.golDarahKlik ) 29| 30| def golDarahKlik(self.show() 26| 27| self. index): 31| self. 80.golDarah ) 19| rb. Darah" ) 12| self. "A".golDarah.setButton(0) # default 23| self. i * lebar.__init__(self) 06| daftarGol = ["Tidak tahu".setTitle( "Gol.golDarah = QButtonGroup( self ) 11| self.setText( gol ) 20| rb.setGeometry(20.golDarah.100.146 BAB 15. VISUAL CLASS 03| class FormRadioButton(QWidget): 04| def __init__(self): 05| QWidget. "AB".golDarah.setCaption( "Golongan %s (%d) dipilih" % . lebar ) 21| i = i + 1 22| self. 13| (jmlGol+2)*lebar) 14| self.golDarah.count()-1) ) 25| self.golDarah. self.setGeometry( 5.

15.6. DAFTAR FLUKTUATIF - QCOMBOBOX
32| 33| 34| 35| 36| 37| app = QApplication([]) fm = FormRadioButton() app.setMainWidget(fm) app.exec_loop()

147

( self.golDarah.find(index).text(), index) )

Jadi jumlah objek-pilihan tergantung dari jumlah datanya dimana penataannya menggunakan suatu rumus yang diletakkan dalam perualangan

for.

Penataan otomatis ini juga dapat di-

lakukan dengan cara lain, yaitu menggunakan (

selected ).

setButton()

layouter.13

menentukan radiobutton mana yang terpilih

Pada contoh di atas fungsi ini dipakai untuk menen-

tukan pilihan deault . Dari sifat-sifat radiobutton yang sudah dibahas sebelumnya, catatan berikut bisa Anda jadikan pedoman: Gunakan radiobutton untuk daftar pilih berjumlah sedikit dan/atau tidak ada perubahan pada saat runtime.

14

15.6 Daftar Fluktuatif - QComboBox
Sebagaimana radiobutton, combobox (QComboBox) juga merupakan daftar pilih. Perbedaannya adalah bahwa combobox lebih eksibel dalam hal isi dimana daftar pilihannya dapat ditambah

13 Lihat halaman 131. 14 Runtime: saat program

berjalan

148

BAB 15. VISUAL CLASS
Gambar 15.4: Combobox

atau dihapus tanpa perlu mengatur kembali tata letak dari setiap pilihan, karena ia merupakan kombinasi antara tombol dan

popup-list .

Keuntungan lain penggunaan combobox adalah: 1. Daftar pilihnya dapat diurutkan secara

descending .

ascending maupun

2. Memiliki editor (QLineEdit). 3. Bila editor diaktifkan, maka tur

autocompletion dapat di-

fungsikan, yaitu suatu tur yang memudahkan pencarian. Pengetikan sebuah huruf saja - misal A - maka combobox akan melengkapinya sesuai dengan daftar pilih yang ada, misalnya Apel. Bila dilanjutkan dengan penekanan Enter maka combobox menganggap Apel telah dipilih yang mana hal ini sama saja dengan meng-klik pilihan Apel. Lebih jelasnya jalankan but.

combobox.py dan cobalah tur terse-

combobox.py ----------01| from qt import * 02| 03| class FormComboBox(QWidget):

15.6. DAFTAR FLUKTUATIF - QCOMBOBOX

149

04| def __init__(self): 05| QWidget.__init__(self) 06| self.setCaption("ComboBox") 07| daftarBuah = ["Pisang", "Jeruk", "Apel", 08| "Mangga", "Pepaya", "Nanas", "Jambu"] 09| self.buah = QComboBox(self) 10| self.buah.insertStrList( daftarBuah ) 11| self.buah.setEditable(1) 12| self.buah.setAutoCompletion(1) 13| self.buah.listBox().sort() 14| self.setCaption( "Ada %d pilihan buah" % 15| self.buah.count() ) 16| self.show() 17| self.connect( self.buah, SIGNAL("activated(int)"), 18| self.buahKlik ) 19| self.connect( self.buah, SIGNAL("highlighted(int)"), 20| self.buahHighlighted ) 21| 22| def buahKlik(self, index): 23| self.setCaption( "Buah %s (%d) dipilih" % 24| ( self.buah.currentText(), index) ) 25| 26| def buahHighlighted(self, index): 27| self.setCaption( "Buah %s (%d) tersorot" % 28| ( self.buah.text( index ), index) ) 29| 30| app = QApplication([]) 31| fm = FormComboBox() 32| app.setMainWidget(fm)

150

BAB 15. VISUAL CLASS
33| app.exec_loop() QComboBox
yang dipakai

Adapun penjelasan mengenai fungsi adalah:

insertStrList() setEditable() currentText() text() listBox() count()

menambah daftar pilih dengan nilai masukan

berupa list. mengaktifkan editor. mengaktifkan tur autocompletion.

setAutoCompletion()

mendapatkan teks yang sedang dipilih. Untuk

mendapatkan nomor index-nya gunakan

currentItem().

mendapatkan teks pada nomor index tertentu. mendapatkan listbox (QListBox) yang merupakan popup-list bagi combobox. jumlah data dalam daftar.

Seperti biasa, sebagai pedoman penggunaan combobox: Gunakan combobox untuk daftar pilih yang banyak dan/atau kerap berubah pada saat runtime.

15.7 Listbox
Listbox mirip dengan combobox yang dapat memuat banyak pilihan dengan kemampuan

scrolling15 .

Perbedaannya ia tidak

15 Scrolling:
pungnya.

melihat isi yang ukurannya melebihi ukuran objek penam-

15.7. LISTBOX
Gambar 15.5: Listbox

151

memiliki editor, namun memungkinkan pemakai untuk memilih lebih dari satu pilihan. da (

listbox1.py

berikut akan menampil-

kan dua listbox kiri dan kanan yang apabila dilakukan klik gan-

double-click16 )

pada yang kiri maka pilihan tersebut akan

berpindah ke yang kanan, begitu pula sebaliknya.

listbox1.py ----------01| from qt import * 02| 03| class FormListBox(QWidget): 04| def __init__(self): 05| QWidget.__init__(self) 06| self.setCaption("ListBox") 07| daftarBuah = ["Pisang", "Jeruk", "Apel", 08| "Mangga", "Pepaya", "Nanas", "Jambu"] 09| label = QLabel(self) 10| label.move( 10, 10 ) 11| label.setText( "Buah-buahan" ) 12| self.buah = QListBox(self) 13| self.buah.setGeometry( 10, 40, 140, 120 ) 14| self.buah.insertStrList( daftarBuah ) 15| self.buah.sort()
16 Double-click:
klik tombol kiri mouse sebanyak dua kali secara cepat.

152

BAB 15. VISUAL CLASS
16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| 41| 42| 43|

label = QLabel(self) label.move( 170, 10 ) label.setText( "Terpilih" ) self.terpilih = QListBox(self) self.terpilih.setGeometry( 170, 40, 140, 120 ) label = QLabel(self) label.setGeometry( 10, 160, 200, 20 ) label.setText("Lakukan klik ganda (double click)") self.show() self.connect(self.buah, SIGNAL("selected(int)"), self.buahSelected) self.connect(self.terpilih, SIGNAL("selected(int)"), self.terpilihSelected) def buahSelected(self, index): self.terpilih.insertItem( self.buah.text(index)) self.terpilih.sort() self.buah.removeItem( index ) def terpilihSelected(self, index): self.buah.insertItem( self.terpilih.text(index)) self.buah.sort() self.terpilih.removeItem( index ) app = QApplication([]) fm = FormListBox() app.setMainWidget(fm) app.exec_loop()

15.7. LISTBOX
Berikut ini beberapa fungsi has:

153

QListBox

di atas yang perlu diba-

sort()

mengurutkan daftar pilihan. menambah data. menghapus data.

insertItem() removeItem() selected()
(

double-click ).

sinyal yang muncul saat listbox di-klik dua kali

Pilihan Ganda - Multiselect
Listbox memang dirancang untuk aplikasi yang membutuhkan suatu masukan dengan pilihan lebih dari satu. dengan satu kali klik pada setiap pilihan.

listbox2.py

berikut memberikan contoh bagaimana kita dapat memilih hanya

listbox2.py ----------01| from qt import * 02| 03| class FormListBox(QWidget): 04| def __init__(self): 05| QWidget.__init__(self) 06| self.setCaption("ListBox") 07| daftarBuah = ["Pisang", "Jeruk", "Apel", 08| "Mangga", "Pepaya", "Nanas", "Jambu"] 09| self.buah = QListBox(self)

buah. VISUAL CLASS 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| self.isSelected( i ): self. 120 ) self. 40. 24 ) btKiri.buah. SIGNAL( "clicked()" ). self. 110. 80.text(i)) self. 140.Multi ) self.sort() i = 0 while i < self. SIGNAL( "clicked()" ).sort() self.insertItem(self.Multi ) btKanan = QPushButton(self) btKanan.isSelected( i ): self. 40.buah.count(): if self.connect( btKiri. self.terpilih.terpilih.btKananKlik ) self.setGeometry( 210.insertStrList( daftarBuah ) self. 120 ) self.terpilih = QListBox(self) self.setSelectionMode( QListBox.154 BAB 15.count() ): if self.buah.buah.setSelectionMode( QListBox.setText( "<" ) self. 24 ) btKanan. 40.removeItem( i ) else: .setText( ">" ) btKiri = QPushButton(self) btKiri.buah. 140.buah.connect( btKanan.terpilih.btKiriKlik ) def btKananKlik(self): for i in range( self.terpilih.buah.setGeometry( 160. 40.buah.setGeometry( 160.setGeometry( 10.show() self.buah.

QListBox.terpilih. LISTBOX 39| 40| 41| 42| 43| 44| 45| 46| 47| 48| 49| 50| 51| 52| 53| 54| 55| 56| i = i + 1 155 def btKiriKlik(self): for i in range( self.buah.isSelected( i ): self.count() ): if self.count(): if self.insertItem(self.removeItem( i ) else: i = i + 1 app = QApplication([]) fm = FormListBox() app.sort() i = 0 while i < self. pilihan tersebut menjadi tidak terpilih lagi.7. artinya bila klik pada suatu pilihan maka bisa memilih lebih dari satu. Pilihan bersi- toggle.Single QListBox.text(i)) self.buah.15.terpilih.isSelected( i ): self.terpilih.terpilih.terpilih.Extended bisa memilih lebih dari satu dengan ter- lebih dahulu menekan Ctrl atau Shift sebelum klik .terpilih. tuhkan masukan berupa: QListBox.exec_loop() Ia membu- setSelectionMode() menentukan metode memilih.Multi fat hanya satu saja yang bisa dipilih.setMainWidget(fm) app.

Metode ini biasanya untuk memilih sekumpulan pilihan pada rangkaian ( tertentu. artinya objek tersebut sedang berinteraksi dengan pemakai. Tidak dapat diklik 2. Tidak bisa difokuskan.6: Disable Widget pada pilihan yang dimaksud. Atau de- ngan kata lain listbox hanya bisa dilihat saja ( only ).py 17 Dalam sebuah form hanya ada satu objek yang fokus (focused ).NoSelection tidak ada yang bisa dipilih. dan Anda tidak dapat memasukkan teks apapun. dengan tandatanda seperti: 1. se- hingga meski tampak namun tidak berfungsi. atau hanya sebuah pilihan saja. range ) QListBox. 17 Kalau objek itu QLineEdit maka kursor tidak dapat berada di sana. . VISUAL CLASS Gambar 15. enable. kecuali dari dalam program. Bila klik saja berarti hanya satu pilihan saja.156 BAB 15.Enable QWidget beserta turunannya dapat dinonaktifkan ( disable ). read- 15.8 Widget Aktif . Objek yang dinonaktifkan akan berubah warnanya untuk membedakan dengan objek yang aktif ( enable ).

berubah) 18| self.tombol.__init__(self) 06| self.setEnabled(0) 14| self.tombol = QPushButton( self ) 11| self. 19| self.setGeometry(5.tombol.15.resize(200. 17| self.setEnabled(0) 24| else: .nama. teks): 22| if teks.nama = QLineEdit( self ) 09| self.tombol.connect(self.80) 08| self.setCaption("Masukkan nama") 07| self. SIGNAL("clicked()"). WIDGET AKTIF .ENABLE berikut berisi sebuah hanya dapat diklik apabila 157 QLineEdit dan sebuah QPushButton yang QLineEdit terisi.setText("&OK") 12| self. 100.setGeometry(5.isEmpty(): 23| self.30) 13| self.30.selesai) 20| 21| def berubah(self. 16| SIGNAL("textChanged( const QString& )").show() 15| self.connect(self.tombol.20) 10| self. enable.nama.5. 60.tombol.py --------01| from qt import * 02| 03| class FormNama(QWidget): 04| def __init__(self): 05| QWidget.8.

158 BAB 15. VISUAL CLASS 25| 26| 27| 28| 29| 30| 31| 32| 33| self. jamdigital.tombol.close() app = QApplication([]) fm = FormNama() app. Dengan demikian fungsi berubah() sebenarnya bisa ditulis cukup seperti ini: 0 yang menandakan suatu objek diaktifkan atau tidak.isEmpty() ) 15. Fungsi def berubah(self.setMainWidget(fm) app.py ------------- . teks): self. Sinyal ini menyertakan isi teksnya yang bertipe QString dimana isEmpty() menghasilkan nilai logika 1 apabila teks kosong.9 LCD QLCDNumber merupakan label dengan tampilan seperti layar kalkulator sederhana.exec_loop() memerlukan masukan berupa nilai logika 1 atau setEnabled() ini berasal dari Sinyal QWidget. textChanged() muncul pada saat teks pada QLineEdit berubah.tombol.setEnabled( not teks. dan 0 bila sebaliknya.setEnabled(1) def selesai(self): self. Contoh berikut ini menampilkan jam digital.

setMainWidget(fm) 24| app.setNumDigits(8) 08| self.display( t ) 17| 18| 19| if __name__ == "__main__": 20| app = QApplication([]) 21| fm = JamDigital(None) 22| fm.startTimer( 500 ) 10| 11| def timerEvent( self. parent) 06| self.toString("hh:mm:ss")) 16| self. parent): 05| QLCDNumber.setSegmentStyle( QLCDNumber.show() 23| app.tampilkan() 13| 14| def tampilkan( self ): 15| t = str(QTime.Flat ) 07| self. e ): 12| self.tampilkan() 09| self. LCD Gambar 15.9.currentTime().__init__(self.exec_loop() .7: LCD 159 01| from qt import * 02| 03| class JamDigital( QLCDNumber ): 04| def __init__( self.15.

2. 3.1 Tanpa Mouse Meski aplikasi window (termasuk KDE) kerap menggunakan mous dalam pengoperasiannya. C. Y. P. 5/S. 9/g. derajat (kutip tunggal pada string-nya) dan spasi. Nilai yang setSegmentStyle() mungkin adalah Flat. Sedangkan pembahasan yang berkaitan dengan waktu dapat dilihat pada halaman 139. A. u.10. 1. menentukan model tampilan.). B. setNumDigits() menentukan jumlah karakter yang boleh tampil. h. 15. yaitu: 0/O. titik dua (:). H. namun sebenarnya tanpa mouse pun dapat dilakukan: • Untuk berpindah dari satu objek ke objek lainnya bisa menggunakan tombol Tab atau Shift-Tab. 8. dan Outline. minus (-). o. 15. Filled. 4. VISUAL CLASS Fungsi yang digunakan pada contoh di atas adalah: display() menampilkan karakter tertentu. r. Karakter lainnya akan ditampilkan sebagai spasi. . titik desimal (. E. 7. F. U.160 BAB 15. 6. D. L.10 Hanya Keyboard Berikut ini pembahasan seputar penggunaan keyboard secara intensif.

setCaption("Alamat") 07| self.130 ) 08| 09| labelNama = QLabel ( 10| self. 161 Untuk menampilkan daftar pilih pada combobox tekan 18 lalu gunakan Up atau Down untuk meny- orot pilihan.10.py --------01| from qt import * 02| 03| class FormAlamat(QWidget): 04| def __init__(self): 05| QWidget.__init__(self) 06| self. HANYA KEYBOARD • Alt-Down.alamat = QLineEdit ( 18 Down: panah bawah self self self self ) ) ) ) . • • • Tekan Spacebar untuk meng-klik tombol. Cara di atas merupakan fasilitas standar yang tidak memerlukan sentuhan programming.nama = QLineEdit ( 11| labelAlamat = QLabel ( 12| self.resize( 270. dan tekan Enter untuk menentukan pilihan.15. Tekan Esc untuk menutup form dialog. Tekan Alt-F4 untuk menutup form. Cara lain adalah menggunakan tombol pintas ( shortcut-key ) yang telah didenisikan melalui QLabel seperti pada contoh berikut: alamat.

setText( "&Alamat" ) btOk.close() app = QApplication([]) fm = FormAlamat() app.24 ) ) ) ) ) labelNama.setBuddy( self.show() self.setMainWidget(fm) app.setText ( "&Nama" ) labelAlamat.connect(btOk.20.180.selesai) def selesai(self): self.20 70.50.setGeometry self.setGeometry labelAlamat. fm. dan dengan menggunakan fungsi setBuddy(). 50.nama ) labelAlamat.20 70.setGeometry self.nama.alamat ) labelNama. SIGNAL("clicked()").20 20.alamat.90.50.text().162 BAB 15. VISUAL CLASS 13| 14| 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| btOk = QPushButton( self ) labelNama. 40. 80.nama.20.setText ( "&OK" ) self.setGeometry ( ( ( ( ( 20.setGeometry btOk.setBuddy ( self.text() labelNama dan labelAlamat yang telah &. self.20 90.180.alamat.exec_loop() print fm. Perhatikan teks pada diberi karakter .

Lebih jelasnya lihat gambar 15. pengurangan (-). nama dan alamat. Pastikan +.2 Tombol Keyboard Program kalkulator berikut ini hanya menampilkan layar angka saja dengan tur sebagai berikut: 1. yaitu untuk menghitung hasil.15.10.8. HANYA KEYBOARD Gambar 15. perkalian (*). dan pembagian (/). Tombol Enter (pada keypad19 ) berarti samadengan (=). Ini artinya bila kita menekan Alt-N. -. 15.8: Tombol pintas (shortcut-key) 163 keduanya dikaitkan dengan di nama). maka nama menjadi fokus (kursor berada Sedangkan bila ditekan Alt-A maka alamat yang terfokus.10. 19 Keypad: kelompok tombol angka dan operasi matematika dasar seperti Biasanya terletak di paling kanan keyboard. Operasi matematika yang dibolehkan adalah penjumlahan (+). lampu indikator numlock menyala untuk mengaktifkannya (tekan tombol .) 3. Pada tampilannya. *. dan /. pemberian karakter btOk yang telah diberi &. Pemisah desimal menggunakan titik (. Begitu pula dengan tombol tombol tersebut. Penekanan Alt-O sama artinya dengan meng-klik mouse pada & ini memberikan garis bawah (underline) pada karakter setelahnya yang berguna sebagai informasi kepada pemakai. 2.

size() ) 10| self.Flat) 11| self.lcd = QLCDNumber(self) 09| self. 20 Posisi tombol Return menjadi satu bagian dengan tombol huruf.lcd. Tombol Escape untuk me- reset.__init__(self) 06| self. Pada laptop. Berguna bagi form lain yang ingin menggunakan form kalkulator untuk mendapatkan hasil perhitungan. Tombol Return 5.setNumDigits(10) 12| self. QLCDNumber akan dipakai untuk memberi kesan kalkulator sebenarnya.py ------------01| from qt import * 02| 03| class FormKalkulator(QDialog): 04| def __init__(self): 05| QDialog.lcd.lcd. Tombol N untuk menegatifkan angka. 6. Bacalah petunjuk penggunaannya. VISUAL CLASS 20 berfungsi sama dengan tombol Enter.resize( self. keypad biasanya diaktifkan dengan menggunakan tombol Fn dan tombol lainnya. namun sekaligus menutup form.120) 08| self.setCaption("Kalkulator") 07| self. kalkulator.reset() NumLock). mengembalikan kondisi seperti baru pertama kali dijalankan. 4.setSegmentStyle(QLCDNumber. .164 BAB 15.resize(640.

a): if not self.intValue() == self.angka() ) def setOperator(self.teks and a == ".lcd.show() def reset(self. a) try: n = float(x) except ValueError: return self.": self.lcd.operator = "" self.display( .lcd.lcd.intValue() else: return self.lcd.value() def setAngka(self.display(x) def negatif(self): self.teks = "0" x = "%s%s" % (self.self.operator = op . HANYA KEYBOARD 13| 14| 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| 41| self.15.teks = "" self.hitung() self.value(): return self.lcd.teks = x self. teks=0): self. op): self.nilai = 0 self.display(teks) 165 def angka(self): if self.teks.lcd.10.

key() == Qt.Key_Escape: self. e): ch = "%s" % e.key() == Qt.setAngka( ch ) .close() def keyPressEvent(self.166 BAB 15.display( self.text() if ch in ["+".Key_N: self.operator.teks = "" self.negatif() elif e.Key_Enter: self.operator: s = "self. VISUAL CLASS 42| 43| 44| 45| 46| 47| 48| 49| 50| 51| 52| 53| 54| 55| 56| 57| 58| 59| 60| 61| 62| 63| 64| 65| 66| 67| 68| 69| 70| def hitung(self): if self.key() == Qt.hitung() elif e.hitung() self."-".setOperator(ch) elif e.nilai ) self.reset() elif e.operator = "" def selesai(self): self.key() == Qt.lcd.nilai = self."*".Key_Return: self.reset("salah") return else: self."/"]: self.value() ) try: exec(s) except ZeroDivisionError: self.nilai = self.nilai %s %s" % \ (self.lcd. self.angka() self.selesai() else: self.

AltButton. event yang memiliki fungsi: 167 21 panggil. mengembalikan nilai atau Qt. adalah contoh konstanta yang sudah disiapkan untuk nilai fungsi ini.ShiftButton.exec_loop() 76| print fm. Qt.setMainWidget(fm) 75| app. sedangkan intValue() menjadi integer.angka() Saat tombol keyboard ditekan. dan Alt. Qt. HANYA KEYBOARD 71| if __name__ == "__main__": 72| app = QApplication([]) 73| fm = FormKalkulator() 74| app. fungsi yang berkaitan dengan suatu kejadian.Key_Return print e. . lalu tekan tombol keyboard yang Anda maksud agar tampil nomornya.Key_Escape. Contoh penggunaannya ada di halaman 158. Event ini menyertakan parameter keyPressEvent() die bertipe QKeyEvent key() mengembalikan nomor (integer) tombol keyboard yang ditekan. value() 21 Event: mencoba mengkonversi nilai yang tampil menjadi oat.key() pada event tersebut. dan Qt. text() state() mengembalikan karakter atau tulisan sesuai dengan tombol yang ditekan.ControlButton. Untuk tombol lainnya dapat diketahui dengan perintah Qt. Qt.15.10.Key_Enter. Control (Ctrl). Ketiganya mewakili tombol Shift.

Xmodmap pada home directory22 yang berisi translasi tombol keycode 79 = 7 keycode 80 = 8 keycode 81 = 9 keycode 83 = 4 keycode 84 = 5 keycode 85 = 6 keycode 87 = 1 keycode 88 = 2 keycode 89 = 3 keycode 90 = 0 keycode 91 = period keycode 77 = keypad berikut ini: Bila Anda superuser root. . le tikan keypad berfungsi sebagai tombol angka.biasanya .168 BAB 15. Hal ini berakibat pada fungsi keypad sebaUntuk memasgai tombol navigasi dan bukan tombol angka.3 NumLock Secara default. simpan script di atas pada /etc/X11/Xmodmap direktori default milik user tertentu. buatlah sebuah . Misalkan usernya agar user lainnya bisa langsung menggunakannya. lampu indikator NumLock tidak menyala ketika seseorang login.10. VISUAL CLASS 15. 22 Home directory: bernama toni maka .home directory baginya adalah /home/toni.

3. total penjualan. kali. Kebebasan mencatat transaksi seperti pemberian discount.Bab 16 Kasir I Kasir I adalah program kasir sederhana namun sudah layak dipakai untuk mencatat transaksi penjualan. Pemakai sudah mengetahui harga jual produknya. seketika. kurang. Struk cukup informatif dimana tercetak rincian nilai. 169 . Tidak memerlukan pencatatan nama barang. yang penting nilainya tercetak. uang yang dibayarkan serta nilai kembaliannya. 4. perubahan harga jual. dan bagi dimungkinkan. 2. Operasi perhitungan dengan operator tambah. Juga tercetak tanggal dan jam transaksi. dsb. Ide pembuatannya adalah: 1.

KASIR I 5. dan terakhir waktu transaksi.500 3.500 1 Lihat halaman 115.170 BAB 16.000 7. pencatatan bisa dialihkan ke le biasa. Tombol Enter berarti mencetak harga barang namun yang tampil di layar LCD adalah totalnya (akumulasi). 7. 6. Berikut ini contoh tampilan pada struk: 2. Bila ada gangguan printer. 2.py pada contoh sebelum- nanti akan mengubah sifat leluhurnya agar sesuai dengan kriteria di atas. Selanjutnya nilai tersebut dikurangi total penjualan dan ditampilkan kembaliannya. Mudah digunakan karena kerap menggunakan keypad. Adapun tur dari forn ini adalah: 1. Informasi yang tercetak adalah total penjualan. Mudah perawatan karena transaksi tidak tersimpan sehingga tidak khawatir ruang harddisk menjadi penuh. Cukup cepat karena nilai langsung tercetak. Program ini beranjak dari nya 1 dimana keturunan FormKalkulator yang bernama FormKasir kalkulator. nilai pembayaran serta kembaliannya. . Tombol Return berarti mengasumsikan nilai yang tampil di layar LCD adalah pembayaran.

argv[1:]: filename = sys. dan Kembali.171 13.argv[1] 15| else: filename = "/dev/lp0" 16| self. "w") 17| self. B. format 04| from os import system 05| import sys 06| from kalkulator import FormKalkulator 07| 08| setlocale(LC_ALL.000 K 290103 16:46 Makna T. LC_ALL.setCaption("Kasir I") 14| if sys.file = open(filename. Baris terakhir merupakan tanggal.total = 0 18| . Bayar.__init__(self) 13| self.000 T 20. dan K berturut-turut adalah Total.000 B 7. kasir1.py --------01| from qt import * 02| from string import rjust 03| from locale import setlocale. tahun dan jam pencetakan. bulan. "") 09| 10| class FormKasir(FormKalkulator): 11| def __init__(self): 12| FormKalkulator.

simpan( w ) self.flush() def cetak(self.simpan(s) def keyPressEvent(self.cetak( kembali.total.f". kode=""): n = format("%2.total ) self. _kode) self.key() == Qt.nilai ) elif e.simpan("\n" * 5) # mudah merobeknya self. "B" ) self. angka.10) _kode = rjust(kode. "K" ) w = QDateTime.cetak( self.currentDateTime().display( self.total = self.self.Key_Return: bayar = self.file.total + self.lcd.reset() self. e): if e.nilai self. 1) _angka = rjust(n.key() == Qt.cetak( bayar.cetak( self.total = 0 .total self. angka.angka() kembali = bayar .2) s = "%s%s\n" % (_angka.write("%s" % s) self.172 BAB 16. s): self. KASIR I 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| 41| 42| 43| 44| 45| 46| 47| def simpan(self. "T" ) self.hitung() self.file.Key_Enter: self.toString( "ddMMyy hh:mm") self.

keyPressEvent(self.py /tmp/kasir. Bila tidak ingin disimpan kemana-mana bisa menggunakan /dev/null $ python kasir1.exec_loop() digunakan untuk mengirimkan string yang suFungsi ini mirip dengan dah di-write().lcd. Fungsi ini mengembalikan nilai bertipe flush() QDateTime juga.173 48| 49| 50| 51| 52| 53| 54| Fungsi self.display( kembali ) else: FormKalkulator. toString() digu- nakan untuk mencetak waktu sesuai dengan bentuk yang sudah ditentukan. e) app = QApplication([]) fm = FormKasir() app. Jadi penyimpanannya memang tidak permanen. currentDateTime()ja le tidak ditutup.txt Perlu diketahui pula bahwa le tersebut akan dikosongkan terlebih dahulu manakala program dijalankan kembali. Sedangkan nya digunakan untuk mendapatkan waktu saat ini. close() hanya saQDateTime adalah class yang berkenaan dengan informasi waktu (tanggal dan jam). Bila ada masalah pada printer maka nama le alternatif bisa disertakan: $ python kasir1.py /dev/null .setMainWidget(fm) app.

174 BAB 16. KASIR I .

Pengelompokan ini mempermudah penataan. QFrame. Wadah lainnya adalah dan QTabWidget. cukup mengubah posisi wadahnya saja. karena posisi objek-objek tersebut relatif terhadap wadahnya. 175 . Form bisa disebut merupakan wadah utama. Wadah non-form tersebut bertujuan untuk mengumpulkan beberapa widget yang memiliki kesamaan sehingga perlu dikelompokkan ( grouping ). Dengan kata lain untuk mengubah posisi sekelompok objek.Container Wadah atau container merupakan objek visual yang dapat menamQTabWidget.Bab 17 Wadah . QButtonGroup. diketahui agar dipergunakan secara tepat. Masing-masing memiliki ciri khas yang perlu pung objek visual lainnya.

CONTAINER QWidget telah digunakan sebagai form. Langsung ditentukan suhunya dengan nilai antara 0 hingga 99 derajat Celcius.py halaman 127.bisa juga disebut panel .176 BAB 17. Ia dilengkapi label di atasnya sebagai keterangan perihal daftar objek yang ada di dalamnya.2 Panel Frame (QFrame) . . 17. sebenarnya ia juga dapat digunakan sebagai wadah di dalam 1 17. Memiliki dua tombol untuk menambah atau mengurangi nilai. 2 Spinbox: editor yang menerima masukan berupa angka. Contoh penggunaannya dapat dilihat dalam suhu.3 Groupbox Groupbox (QButtonGroup) pada bahasan sebelumnya juga dikategorikan sebagai wadah. ini biasanya dipakai untuk objek sejenis. Objek yang digunakan adalah Class box 2 (QSpinBox). Mari membuat simulasi pengendalian suhu yang dapat dilakukan melalui dua cara: 1. namun 17.merupakan wadah yang bisa diatur model bingkainya. WADAH .1 Widget Meski selama ini form.py di halaman 124. spin- 1 Lihat tab.

suhu. 26-40 derajat Celcius tergolong hangat. 177 2. maka radiobutton akan berubah pula sesuai dengan nilai-antara ( ini: range ) berikut • • • 0-25 derajat Celcius tergolong dingin. yaitu: dinObjek yang digunakan adalah Dua pengendali ini akan saling mempengaruhi satu sama lain. hangat berarti 40 derajat Celcius. dalam keadaan yang sebenarnya mungkin Anda perlu memastikan bahwa nilai-antara di atas memang sesuai dengan kondisi lingkungan. panas berarti 60 derajat Celcius. bila pengendalian melalui radiobutton maka spinbox akan menunjukkan nilai berikut: • • • dingin berarti 25 derajat Celcius. Bila Anda mengubahnya melalui spinbox. hangat.17.py ------01| from qt import * . radiobutton (QButtonGroup). Melalui pilihan yang mewakili suhu tertentu. GROUPBOX gin. 41-99 derajat Celcius tergolong panas.3. Hati-hati. Begitu pula sebaliknya. dan panas.

Dial.StyledPanel ) 16| panelMeter.10.setFrameShadow( QFrame.100) 23| 24| panelSuhu = QFrame(self) 25| panelSuhu.Dial = QDial(panelMeter) 22| self.10.setGeometry(140.__init__(self) 10| self.LCD = QLCDNumber(panelMeter) 19| self.50.30) .23) 20| 21| self.178 BAB 17.160) 15| panelMeter.CONTAINER 02| 03| class FormSuhu(QWidget): 04| Dingin = 25 05| Hangat = 40 06| Panas = 60 07| 08| def __init__(self): 09| QWidget.60.setGeometry(10. WADAH .Sunken ) 28| 29| labelSuhu = QLabel( panelSuhu ) 30| labelSuhu.setGeometry(10.LCD.setFrameShadow ( QFrame.10. 180 ) 12| 13| panelMeter = QFrame(self) 14| panelMeter.setFrameShape( QFrame.setFrameShape( QFrame.100.110.setGeometry(10.WinPanel ) 27| panelSuhu.Raised ) 17| 18| self.resize( 260.50) 26| panelSuhu.setCaption( "Temperatur" ) 11| self.120.10.setGeometry(30.50.

60.suhu.96.setGeometry(10.suhuBerubah) self.rbPanas.setGeometry(10.rbHangat.WordBreak | QLabel. GROUPBOX 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| 41| 42| 43| 44| 45| 46| 47| 48| 49| 50| 51| 52| 53| 54| 55| 56| 57| 58| 59| 179 labelSuhu. SIGNAL( "clicked(int)").suhu.20) grupSuhu = QButtonGroup(self) grupSuhu. SIGNAL( "valueChanged(int)" ).20) self.AlignVCenter) self.3.110.suhu = QSpinBox( panelSuhu ) self.rbDingin = QRadioButton(grupSuhu) self. self.rbDingin.setGeometry(10.rbHangat = QRadioButton(grupSuhu) self.17.setText("Suhu (Celcius)") labelSuhu.rbHangat. self.40.96.20) self.setGeometry(65.setText("Panas") self.grupSuhuBerubah ) self.10.setGeometry(140.setText("Dingin") self.rbPanas = QRadioButton(grupSuhu) self.96.20.80.ubah = 1 .setTitle("Bagi Manusia") self.90) grupSuhu.setAlignment( QLabel.connect( grupSuhu.40.rbPanas.connect(self.setText("Hangat") self.rbDingin.20) self.

rbDingin.setValue( self.setChecked(1) 70| elif self.Hangat ) 84| else: 85| self.ubah = 1 76| 77| def grupSuhuBerubah(self.ubah = 0 80| if index == 0: 81| self.value() in range(self.suhu.Panas): 72| self.Dingin+1.suhu.setChecked(1) 73| else: 74| self.suhu.setValue( self.LCD.Dingin ) 82| elif index == 1: 83| self.setValue( self.180 BAB 17. WADAH .Panas ) 86| self.CONTAINER 60| self.display( nilai ) 65| self.ubah: 79| self.ubah = 0 68| if self.ubah = 1 87| 88| app = QApplication([]) .ubah: 67| self.show() 62| 63| def suhuBerubah(self.rbHangat.setValue( self.setChecked(1) 75| self. nilai): 64| self.rbPanas.Dingin+1): 69| self.Dial. index): 78| if self.suhu. 71| self.value() in range(self.setValue( nilai ) 66| if self.suhu.Dingin ) # default 61| self.suhu.

QButtonGroup. 3 Atau lebih tepat dikatakan terjadi rekursif tak berkesudahan. maka diperlukan pembeda pada saat suatu nilai berubah.3. daya tarik suhu.exec_loop() QSpinBox 181 memiliki nilai-antara 0 hingga 99 (default) dimana Class ini memiliki sinyal nilainya berupa integer yang dapat diubah menggunakan fungsi setValue(). baik oleh pemakai secara langsung atau melalui suhuBerubah() dipanggil pada saat QSpinBox nilainya berubah.ubah merupakan variabel logika untuk mengatasi permasalahan tersebut. Rekursif: .17. valueChanged() yang timbul pada saat nilainya berubah.py adalah adanya saling mempengaruhi objek satu dengan lainnya. Variabel 3 self. Karena bisa menimbulkan perulangan yang tak berkesudahan . dan dengan demikian rekursif tak berkesudahan dapat dihindari. Masing-masing fungsi harus bisa membedakan apakah ia dipanggil melalui cara pertama (oleh pemakai langsung) atau melalui cara kedua (melalui fungsi). Fungsi akan mengubah posisi jarum. Hal serupa terjadi dengan grupSuhuBerubah() yang berkaitan dengan perubahan pilihan pada QButtonGroup. GROUPBOX 89| fm = FormSuhu() 90| app.setMainWidget(fm) 91| app. Sedangkan juga memiliki nilai-antara 0 hingga 99. fungsi yang memanggil dirinya sendiri. QDial memiliki tampilan seperti speedometer yang setValue()-nya Sinyal yang Saling Terkait Dari sudut teknik pemrograman.

TabWidget.290.TabWidget) 11| self. "Alamat") 13| self. WADAH .tabAlamat = QWidget(self. tab. dimana keduanya disatukan berada dalam wadah yang berbeda namun disatukan dalam QTabWidget.setText("Jalan") 19| self.insertTab(self.CONTAINER 17.setGeometry(11.182 BAB 17.py -----01| from qt import * 02| 03| class FormIdentitas(QWidget): 04| def __init__(self): 05| QWidget.TabWidget. tab.20.tabInternet = QWidget(self.11.20) 18| labelJalan.py berikut menun- jukkan dua kelompok identitas seseorang yaitu: alamat rumah dan alamat internet.insertTab(self.jalan = QLineEdit(self.TabWidget = QTabWidget(self) 09| self.tabAlamat) .tabInternet.210) 10| self.66.TabWidget) 12| self.4 Multigroup Objek lain yang mirip groupbox namun dapat memiliki wadah lebih dari satu adalah QTabWidget."Internet" 14| 15| # Isi tabAlamat 16| labelJalan = QLabel(self.tabAlamat) 17| labelJalan.TabWidget.tabAlamat.setGeometry(20.setCaption( "Identitas" ) 07| 08| self.__init__(self) 06| self.

tabAlamat) self.setGeometry(83.tabAlamat) self.89.66.tabAlamat) self.kecamatan = QLineEdit(self.20) labelKodePos = QLabel(self.20) labelKec.setGeometry(83.jalan.setText("Kecamatan") self. "kodePos") self.tabAlamat.66.setText("Propinsi") self.tabAlamat) labelKec.4.20) labelPropinsi = QLabel(self.setGeometry(83.setGeometry(83.63.kecamatan.37.setText("Kode Pos") self.20) labelTelp = QLabel(self.37.setGeometry(83.setText("Kelurahan") self.66.tabAlamat) labelKodePos.17.20) labelKodePos.66.196.66.tabAlamat) labelPropinsi.20) labelKec = QLabel(self.196.70.setGeometry(11.20) labelPropinsi. MULTIGROUP 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| 41| 42| 43| 44| 45| 46| 47| 48| self.115.20) labelTelp.kelurahan = QLineEdit(self.11.setGeometry(11.tabAlamat) labelTelp.115.63.kodePos.20) labelKel.141.20) 183 labelKel = QLabel(self.propinsi = QLineEdit(self.196.setGeometry(11.setGeometry(11.propinsi.kelurahan.kodePos = QLineEdit(self.setGeometry(11.setText("Telp") .196.tabAlamat) labelKel.89.

37.setGeometry(58.web = QLineEdit(self.20) self.211.tabInternet) self.tabInternet) labelYahoo.setGeometry(11.89.184 BAB 17.37.tabInternet) labelEmail.setText("Email") self.setText("Web") self.211.email = QLineEdit(self.yahoo.11.20) labelIcq.41.41.setGeometry(58.63.setGeometry(11.setGeometry(11.tabInternet) labelWeb.20) # Isi tabInternet labelEmail = QLabel(self.email.yahoo = QLineEdit(self.setGeometry(11.icq.tabInternet) labelIcq.show() .tabInternet) self.web.20) labelYahoo.20) labelYahoo = QLabel(self.setGeometry(83.tabAlamat) self.setGeometry(58.setText("ICQ") self.telp = QLineEdit(self.setText("Yahoo") self.20) labelEmail.tabInternet) self.211.tabInternet) self.211.CONTAINER 49| 50| 51| 52| 53| 54| 55| 56| 57| 58| 59| 60| 61| 62| 63| 64| 65| 66| 67| 68| 69| 70| 71| 72| 73| 74| 75| 76| 77| self.icq = QLineEdit(self.20) labelWeb = QLabel(self.11. WADAH .63.141.setGeometry(58.41.20) labelWeb.41.196.20) labelIcq = QLabel(self.89.telp.

exec_loop() insertTab() digunakan untuk menambah kelompok baru.setMainWidget(fm) app. . sedangkan yang kedua berupa string sebagai nama kelompok.17.4. Masukan pertamanya adalah wadah. MULTIGROUP 78| 79| 80| 81| 82| Fungsi 185 app = QApplication([]) fm = FormIdentitas() app.

186 BAB 17. WADAH .CONTAINER .

ngan ukuran QTextEdit. Untunglah Qt menyediakan masuk ukurannya. layouter (QLayout beserta turunannya) untuk menata widget secara otomatis. mana hal itu dilakukan ? 187 .1 Fleksibilitas Ukuran Anda pernah melihat sebuah text editor seperti la melihat contoh sebelumnya. Lalu bagai- kwrite kwrite ? Bi- tampak dibangun de- Ya. ter- 18.Bab 18 Penataan Menentukan posisi dan ukuran widget memang merupakan pekerjaan tersendiri. ternyata ukuannya mengikuti besarnya form. Cobalah menjalankan kwrite dan perhatikan QTextEdit-nya saat Anda mengubah-ubah ukuran form.

exec_loop() addWidget() saat runtime. maka salah satunya dapat digunakan dengan hasil yang sama. ukuran QTextEdit akan mengikuti ukuran form.editor ) 10| self. Selanjutnya akan kita tambahkan sebuah panel (QFrame) di Panel ini hanya mengikuti panjang . digunakan untuk menambahkan widget ke dalam Sebagaimana "daftar penataan".__init__(self) 06| self.188 BAB 18. Cobalah mengubah-ubah ukuran form pada kwrite.editor = QTextEdit(self) 08| layout = QVBoxLayout(self) 09| layout.setMainWidget(fm) 15| app.addWidget( self. atas editor (QTextEdit). PENATAAN Qt menyediakan sebuah layouter QVBoxLayout dan QHBoxLayout yang bertugas mengatur ukuran dan posisi widget secara vertikal dan horizontal.py -------------01| from qt import * 02| 03| class FormEditor(QWidget): 04| def __init__(self): 05| QWidget. Bila hanya ada satu widget. texteditor1.setCaption("Text Editor") 07| self.show() 11| 12| app = QApplication([]) 13| fm = FormEditor() 14| app.

setMinimumHeight(40) 10| layout = QVBoxLayout(self) 11| layout. dan ammenjadi ati perbedaannya.py -------------01| from qt import * 02| 03| class FormEditor(QWidget): 04| def __init__(self): 05| QWidget.show() 14| 15| app = QApplication([]) 16| fm = FormEditor() 17| app.editor = QTextEdit(self) 08| panel = QFrame (self) 09| panel. Fungsinya nanti sebagai texteditor2. FLEKSIBILITAS UKURAN tempat tombol-tombol menu pada contoh berikutnya. sedangkan lebarnya tetap.__init__(self) 06| self. Latihan Gantilah QVBoxLayout menjadi QHBoxLayout.exec_loop() setMinimumHeight() digunakan untuk menentukan lebar minimum widget.setMainWidget(fm) 18| app. 189 form saja.addWidget( panel ) 12| layout. coba ganti setMinimumHeight() setMinimumWidth().18. Bila Anda kehilangan panel.setCaption("Text Editor") 07| self.1. Tanpanya panel tidak akan terlihat.addWidget( self. .editor ) 13| self.

yaitu: Baru Mengosongkan editor untuk membuat le baru .exec_loop() 18.setCaption("Text Editor") 07| layout = QVBoxLayout(self) 08| layout.190 BAB 18.2 Fleksibilitas Posisi Kini tombol menu akan diletakkan di dalam panel.setAutoAdd(1) 09| panel = QFrame(self) 10| panel. PENATAAN bisa diganti dengan fungsi addWidget() tis.setMinimumHeight(40) 11| self.setMainWidget(fm) 17| app. setAutoAdd() yang memasukkan widget ke dalam daftar penataan secara otoma- texteditor2a.py --------------01| from qt import * 02| 03| class FormEditor(QWidget): 04| def __init__(self): 05| QWidget.__init__(self) 06| self.editor = QTextEdit(self) 12| self.show() 13| 14| app = QApplication([]) 15| fm = FormEditor() 16| app.

setText ( "Baru" ) 20| btBuka.editor = QTextEdit ( self ) 11| 12| layout = QHBoxLayout( panel ) 13| layout.setAutoAdd(1) 14| btBaru = QPushButton( panel ) 15| btBuka = QPushButton( panel ) 16| btSimpan = QPushButton( panel ) 17| btSimpanSbg = QPushButton( panel ) 18| 19| btBaru.18.setCaption("Text Editor") 07| layout = QVBoxLayout( self ) 08| layout.setText ( "Simpan" ) 22| btSimpanSbg.2.setAutoAdd(1) 09| panel = QFrame ( self ) 10| self.__init__(self) 06| self.setText( "Simpan Sebagai" ) .py -------------01| from qt import * 02| 03| class FormEditor(QWidget): 04| def __init__(self): 05| QWidget. FLEKSIBILITAS POSISI Buka Simpan Membuka le dan menampilkannya pada editor Menyimpan le 191 Simpan_Sebagai Menyimpan dengan nama le lain texteditor3.setText ( "Buka" ) 21| btSimpan.

setMainWidget(fm) app. ukuran tombol juga ikut memOleh karena itu ini Tentu saja tampilannya tidak lagi nyaman dipandang. Sepantasnya ukuran tombol tidak berubah. kini lagi. Sedangkan showMaximized() form hingga memenuhi layar desktop. namun ketika form diperbesar ( besar. Semua tombol sudah tertata sesuai urutannya. di- QBoxLayout.192 BAB 18. Fungsi QHBoxLayout dan QVBoxLayout. texteditor3a. PENATAAN 23| 24| 25| 26| 27| 28| 29| self. Kelihatannya yang bisa mempengaruhi ukuran minimum parent-nya.showMaximized() app = QApplication([]) fm = FormEditor() app.__init__(self) 06| self.exec_loop() setMinimumHeight() sudah tidak diperlukan QPushButton memiliki ukuran minimum berguna untuk memperbesar Perhatikan.py --------------01| from qt import * 02| 03| class FormEditor(QWidget): 04| def __init__(self): 05| QWidget. maximized ). leluhur addStretch(). mana kita bisa menggunakan fungsi milik dibutuhkan pengganjal yang akan memenuhi sisa ruang.setCaption("Text Editor") .

setText ( btSimpan. Namun mungkin masih ada yang kurang pas. FLEKSIBILITAS POSISI 07| 08| 09| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| layout = QVBoxLayout( self ) layout.setText ( btSimpanSbg.addStretch() btBaru = QPushButton( btBuka = QPushButton( btSimpan = QPushButton( btSimpanSbg = QPushButton( btBaru. .setText( self.showMaximized() app = QApplication([]) fm = FormEditor() app.18.setText ( btBuka.2.setMainWidget(fm) app. karena posisinya tidak berada di sisi kiri form melainkan di sisi kanan. kini ukuran tombol lebih nyaman dilihat. Perlu sedikit perubahan agar sesuai dengan yang dimaksud.editor = QTextEdit ( self ) layout = QHBoxLayout( layout.exec_loop() panel ) panel panel panel panel ) ) ) ) 193 "Baru" ) "Buka" ) "Simpan" ) "Simpan Sebagai" ) Ya.setAutoAdd(1) layout.setAutoAdd(1) panel = QFrame ( self ) self.

setAutoAdd(1) 09| panel = QFrame(self) 10| self.setText ( "Buka" ) 24| btSimpan.setText ( "Simpan" ) 25| btSimpanSbg.194 BAB 18.setText ( "Baru" ) 23| btBuka.addStretch() 15| layout.showMaximized() . PENATAAN texteditor3b.__init__(self) 06| self.py --------------01| from qt import * 02| 03| class FormEditor(QWidget): 04| def __init__(self): 05| QWidget.setCaption("Text Editor") 07| layout = QVBoxLayout(self) 08| layout.editor = QTextEdit(self) 11| 12| layout = QHBoxLayout( panel ) 13| layout.setDirection( QBoxLayout.setText( "Simpan Sebagai" ) 26| 27| self.RightToLeft ) 16| 17| btSimpanSbg = QPushButton( panel ) 18| btSimpan = QPushButton( panel ) 19| btBuka = QPushButton( panel ) 20| btBaru = QPushButton( panel ) 21| 22| btBaru.setAutoAdd(1) 14| layout.

baik ukuran maupun posisi . 2. dapat diambil beberapa kesimpulan: 1.3 Layout Dengan Metode Grid Dengan QHBoxLayout dan QVBoxLayout dapat menata objek de- ngan arah horizontal maupun vertikal.18.bukan suatu wadah. Layouter akan memenuhi wadah (parent) dengan widget (child) yang diaturnya. 18. Namun untuk penataan .setMainWidget(fm) app.3.exec_loop() 195 setDirection() digunakan untuk menentukan arah penataan. LAYOUT DENGAN METODE GRID 28| 29| 30| 31| 32| app = QApplication([]) fm = FormEditor() app. Fungsi ini dimiliki oleh stanta berikut ini: QBoxLayout dan dapat diisi dengan kon- LeftToRight RightToLeft Down Up dari kiri ke kanan (horizontal) dari kanan ke kiri (horizontal) dari atas ke bawah (vertikal) dari bawah ke atas (vertikal) Dari beberapa contoh di atas tentang penggunaan layouter. Layouter hanya berfungsi sebagai penata widget .

1) 19| self.0) 17| layout.addWidget(labelNama.0) 16| layout.1) 18| layout. 0. 1.nama = QLineEdit( self ) 12| self.setMargin(5) 09| labelNama = QLabel ( self ) 10| labelAlamat = QLabel ( self ) 11| self.show() 20| 21| app = QApplication([]) 22| fm = FormAlamat() . 0.setText ("Alamat") 15| layout. PENATAAN tab. yaitu menggunakan koordinat berdasarkan baris dan kolom.meskipun bisa dengan dua class tersebut.py di halaman 127 tentu cukup mere- widget seperti pada potkan .alamat = QLineEdit( self ) 13| labelNama. Qt memiliki QGridLayout yang menata objek dengan sistem tabel ( grid ).nama.addWidget(self.setCaption("Alamat") 07| layout = QGridLayout( self ) 08| layout.__init__(self) 06| self.alamat.addWidget(self.196 BAB 18. 1.setText ("Nama") 14| labelAlamat.addWidget(labelAlamat. alamat1.py ---------01| from qt import * 02| 03| class FormAlamat(QWidget): 04| def __init__(self): 05| QWidget.

setMargin(5) 10| labelNama = QLabel ( self ) 11| self.py ---------01| from qt import * 02| 03| class FormAlamat(QWidget): 04| def __init__(self): 05| QWidget.setCaption("Alamat") 07| layout = QGridLayout( self.__init__(self) 06| self. alamat2. dilanjutkan ke Karena itu jumlah baris dan dipakai dimana urutan penataan dimulai dari baris pertama kolom pertama dilanjutkan ke kolom berikutnya pada baris yang sama. addWidget() membutuhkan informasi tambahan berupa baris setAutoAdd() juga bisa Jika pada baris tersebut sudah penuh. kolom perlu ditentukan pada saat pembuatan QGridLayout. begitu seterusnya.exec_loop() setMargin() dimiliki oleh 197 berfungsi untuk memberi jarak antara widget de- ngan wadahnya agar tampilan tampak lebih baik.setAutoAdd(1) 09| layout. LAYOUT DENGAN METODE GRID 23| app.setMainWidget(fm) 24| app. baris kedua.2 ) 08| layout. QLayout. QGridLayout dan QBoxLayout.nama = QLineEdit( self ) . adalah setSpacing() yang memberi Fungsi ini dan kolom widget yang akan ditata. 2. leluhur Fungsi lain yang mirip jarak antar widget.18.3.

setText ("Nama") labelAlamat.setMainWidget(fm) app.show() app = QApplication([]) fm = FormAlamat() app.setText("Alamat") self.198 BAB 18.exec_loop() .alamat = QLineEdit( self ) labelNama. PENATAAN 12| 13| 14| 15| 16| 17| 18| 19| 20| 21| labelAlamat = QLabel ( self ) self.

dan milidetik.1 Jam QTime adalah class yang memuat jam. Baris berikut contoh untuk membuat jam: j = QTime( 23. menit. Berikut ini fungsi yang sering dipakai: currentTime() mengembalikan waktu saat ini yang juga bertipe QTime. 19. 45. yaitu (jam). 199 . 55. menit. detik.Bab 19 Waktu Qt memiliki class khusus berkaitan dengan waktu. 0 ) Nilai masukan di atas berturut-turut adalah: jam. hingga milidetik. dan QDateTime QTime (tanggal dan jam). QDate (tanggal). detik.

WAKTU jam menit detik milidetik detik dimana hour() minute() second() msec() addSecs(n ) tambah n QTime..23 atau 1... secsTo(t ) toString() n integer.59) detik tanpa nol di depan (0.999) milidetik dengan nol di depan (000.200 BAB 19. menampilkan jam sesuai dengan format yang dike- hendaki.12 jika ditampilkan dengan AM/PM) m mm s ss z zzz menit tanpa nol di depan (0. mengembalikan selisih detik (integer) dengan t (QTime)....59) menit dengan nol di depan (00....23 atau 01.12 jika ditampilkan dengan AM/PM) hh jam dengan nol di depan (00..59) milidetik tanpa nol di depan (0. Adapun pola yang bisa digunakan dalam fungsi ini adalah: h jam tanpa nol di depan (0.59) detik dengan nol di depan (00.999) .

menampilkan am/pm. jumlah hari di bulan daysInMonth() daysInYear() month() jumlah hari di tahun year() . TANGGAL . juga mengembalikan QDate.QDATE AP ap menampilkan AM/PM. 31 ) dan tentunya ada sudah tahu makna urutannya.2 Tanggal . bulan. 12. urutan hari dalam tahun. fungsi yang sering digunakan: Berikut ini currentDate() year() month() day() tanggal saat ini. urutan hari dalam minggu dimana Senin = 1 dan dayOfWeek() dayOfYear() Minggu = 7.QDate QDate memuat tanggal. bulan. tahun. dan tahun. 19.2. 201 Contoh penggunaannya ada pada halaman 111. tanggal.19. Contoh: t = QDate( 2002.

202 BAB 19.Sunday) M MM MMM bulan tanpa awaln nol (1-12) bulan dengan awalan nol (01-12) nama pendek bulan dalam bahasa Inggris (Jan Dec) MMMM yy yyyy nama panjang bulan (January . QDate.December) dua angka tahun (00-99) empat angka tahun (0000-9999) . QDate. Format yang bisa digunakan adalah: tanggal (day) tanpa awalan nol (1-31) tanggal (day) dengan awalan nol (01-31) nama hari yang pendek dalam bahasa Inggris (Mon . mengembalikan selisih hari dengan teger. mengembalikan QDate.Sun) dddd nama hari yang panjang dalam bahasa Inggris (Monday . mengembalikan in- menampilkan tanggal sesuai dengan format yang dikehendaki. d (QDate). WAKTU menambah addDays(n ) addYears() daysTo(d ) toString() d dd ddd n n hari. addMonths(n ) menambah n bulan. mengembalikan menambah tahun.

19.2. TANGGAL - QDATE
hasa Indonesia. Format yang ditambahkan adalah: hari bulan pasaran nama hari (Senin - Minggu) nama bulan (Januari - Desember) nama pasaran (Pon - Pahing)

203

Class ini bisa kita denisi ulang (reimplementation) agar berba-

Class-nya dinamakan

Tanggal dan termuat dalam modul tanggal.py

agar dapat digunakan program lainnya:

tanggal.py ---------01| from qt import * 02| import string 03| 04| class Tanggal(QDate): 05| Hari = ["Senin","Selasa","Rabu","Kamis", 06| "Jumat","Sabtu","Minggu"] 07| Bulan = ["Januari","Februari","Maret","April","Mei", 08| "Juni","Juli","Agustus","September","Oktober", 09| "November","Desember"] 10| Pasaran = ["Pon","Wage","Kliwon","Legi","Pahing"] 11| 12| # Konstanta: 1-2-2003 Pon 13| TGL = QDate(2003,2,1) 14| 15| def __init__(self, y, m, d): 16| QDate.__init__(self, y, m, d)

204

BAB 19. WAKTU
17| 18| def toString(self, 19| format="hari pasaran, dd bulan yyyy"): 20| s = str(QDate.toString(self, format)) 21| if string.find(s, "hari") > -1: 22| hari = self.Hari[self.dayOfWeek()-1] 23| s = string.replace(s, "hari", hari) 24| if string.find(s, "bulan") > -1: 25| bln = self.Bulan[self.month()-1] 26| s = string.replace(s, "bulan", bln) 27| if string.find(s, "pasaran"): 28| jml = self.TGL.daysTo(self) 29| sisa = jml % 5 30| psr = self.Pasaran[sisa] 31| s = string.replace(s, "pasaran", psr) 32| return QString(s) 33| 34| 35| if __name__ == "__main__": 36| n = QDate.currentDate() 37| t = Tanggal(n.year(), n.month(), n.day()) 38| print t.toString()

19.3 Tanggal dan Jam
QDateTime
adalah gabungan

QDate

dan

QTime.

Inisialisasinya

juga melibatkan dua class tersebut:

t = QDate.currentDate()

19.4. TIMER
j = QTime.currentTime() w = QDateTime( t, j )
Adapun fungsi yang sering digunakan adalah:

205

currentDateTime() date() time()

waktu saat ini, mengembalikan

QDateTime.

mengembalikan porsi tanggal (QDate). mengembalikan porsi jam (QTime). menampilkan waktu sesuai format dimana format

toString()

tersebut sama dengan yang berlaku pada

QTime.

QDate dan

Fungsi lainnya mirip dengan yang terdapat pada QDate maupun QTime seperti addDays(), addMonths(), addYears(), addSecs(), daysTo(), dan secsTo().

19.4 Timer
Pewaktu atau atu

proses di waktu tertentu, misalnya setiap 1 detik.
QObject

timer adalah mesin yang dapat menjalankan suFitur yang merupakan leluhur semua class

ini dimiliki oleh pada Qt.

startTimer()
Class

berfungsi untuk menjalankan timer dan pada

contoh di halaman 111 ia melaksanakan event setiap 500 milidetik (setengah detik).

timerEvent()

WaktuDigital

di bawah ini juga merupakan jam digi-

tal namun dengan informasi yang lebih lengkap.

206

BAB 19. WAKTU
waktudigital.py --------------01| from qt import * 02| from tanggal import Tanggal 03| 04| class WaktuDigital(QLabel): 05| def __init__(self, parent): 06| QLabel.__init__(self, parent) 07| self.startTimer( 500 ) 08| 09| def timerEvent(self, e): 10| w = QDateTime.currentDateTime() 11| t = w.date() 12| tgl = Tanggal( t.year(), t.month(), t.day() ) 13| _tgl = tgl.toString("hari pasaran d bulan yyyy") 14| _jam = w.time().toString("hh:mm:ss") 15| s = "%s %s" % (_tgl, _jam) 16| self.setText( s ) 17| 18| 19| if __name__ == "__main__": 20| app = QApplication([]) 21| fm = WaktuDigital(None) 22| fm.resize(300,50) 23| fm.show() 24| app.setMainWidget(fm) 25| app.exec_loop()

Bab 20

Form Dialog
Form dialog (QDialog) dibangun dengan konsep untuk melaksanakan suatu fungsi form yang singkat, misalnya menampilkan pesan, pengisian username dan password untuk login, dsb.

QDialog biasanya dipanggil dari form lain yang menjadi parentnya. Beberapa turnya antar lain: 1. Fungsi

menghasilkan

accept() untuk menutup form sehingga result() QDialog.Accepted. Biasanya untuk "mengreject() juga menutup form, namun result() QDialog.Rejected yang berarti membatalkan in-

iya-kan" input. 2. Fungsi bernilai put. 3. Bila Enter ditekan sama artinya dengan meng-klik tombol 207

208

BAB 20. FORM DIALOG
default. Default tidaknya suatu tombol dapat diset dengan fungsi

QPushButton.setDefault().

4. Bila Escape ditekan sama artinya dengan pemanggilan

reject().

dialog.py --------01| from qt import * 02| 03| class FormNama(QDialog): 04| def __init__(self, parent): 05| QDialog.__init__(self, parent) 06| self.setCaption("Nama") 07| layout = QVBoxLayout( self ) 08| layout.setAutoAdd(1) 09| 10| self.nama = QLineEdit( self ) 11| wadah = QWidget ( self ) 12| 13| layout = QHBoxLayout( wadah ) 14| layout.setAutoAdd(1) 15| self.tombolOK = QPushButton( wadah ) 16| self.tombolBatal = QPushButton( wadah ) 17| 18| self.tombolOK.setText ("&OK") 19| self.tombolBatal.setText ("&Batalkan") 20| self.tombolOK.setDefault(1) 21| self.connect(self.tombolOK, SIGNAL("clicked()"), 22| self.ok)

20.1. FILE DIALOG
23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39|

209

self.connect(self.tombolBatal, SIGNAL("clicked()"), self.batal) def ok(self): self.accept() def batal(self): self.reject() app = QApplication([]) fm = FormNama(None) fm.show() fm.exec_loop() if fm.result() == QDialog.Accepted: print "Inputnya:", fm.nama.text() else: print "Input dibatalkan" exec_loop()
pada form menyebabkan alur proyang kerap dijumpai pada

Pemanggilan

gram terhenti hingga form tersebut ditutup. Kondisi ini biasa disebut sebagai

showmodal

QDialog.

Class ini merupakan basis bagi dialog lainnya seperti yang

QMessageBox,

sering ditemui dalam berbagai aplikasi, antara lain: atau

QInputDialog.

QFileDialog,

20.1 File Dialog
File dialog (QFileDialog) digunakan untuk hal yang berkaitan
dengan le. Form ini berisi daftar nama le dan direktori ser-

FORM DIALOG Gambar 20. akan melengkapi fungsi tersebut. Tombol-tombol text editor pada contoh sebelumnya belum berfungsi sebagaimana mestinya.editor.setCaption("Text Editor") 07| layout = QVBoxLayout( self ) 08| layout.setAutoAdd(1) 17| layout.__init__(self) 06| self.editor.py -------------01| from qt import * 02| 03| class FormEditor(QWidget): 04| def __init__(self): 05| QWidget.py berikut ini texteditor4.setFamily("Courier") 13| self. membuat direktori.setAutoAdd(1) 09| panel = QFrame ( self ) 10| self. dsb.editor = QTextEdit( self ) 11| font = self.210 BAB 20.addStretch() .font() 12| font.setFont( font ) 14| 15| layout = QHBoxLayout( panel ) 16| layout.1: File Dialog ta memiliki fungsi lainnya seperti pindah direktori. texteditor4.

setFilename( None ) self.setDirection( QBoxLayout.write( "%s" % self. SIGNAL("clicked()"). filename): self. self.connect(btBaru. SIGNAL("clicked()").editor.RightToLeft ) btBaru.close() def setFilename(self.setText ( btSimpan.setText ( btBuka.text() ) f.1. self.baru) self. "w" ) f.buka) self.filename = filename . filename): f = open( filename. FILE DIALOG 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| 41| 42| 43| 44| 45| 46| btSimpanSbg btSimpan btBuka btBaru = = = = QPushButton( QPushButton( QPushButton( QPushButton( panel panel panel panel ) ) ) ) 211 layout.simpan) self.20. self. SIGNAL("clicked()"). self.connect(btBuka.connect(btSimpan.setText ( btSimpanSbg.showMaximized() self.setText( "Baru" ) "Buka" ) "Simpan" ) "Simpan Sebagai" ) self. SIGNAL("clicked()").connect(btSimpanSbg.simpanSbg) def _simpan(self.

getSaveFileName() 70| if not filename.setText( "%s" % f._simpan( _filename ) 73| self.isEmpty(): 56| _filename = "%s" % filename 57| f = open( _filename ) 58| self.filename ) 65| else: 66| self.filename) 48| 49| def baru(self): 50| self.setFilename( _filename ) 74| 75| app = QApplication([]) ._simpan( "%s" % self.close() 60| self.212 BAB 20.isEmpty(): 71| _filename = "%s" % filename 72| self.read() ) 59| f.setCaption("Text Editor . FORM DIALOG 47| self.setFilename( None ) 52| 53| def buka(self): 54| filename = QFileDialog(self).setFilename( _filename ) 61| 62| def simpan(self): 63| if self.%s" % self.clear() 51| self.getOpenFileName() 55| if not filename.simpanSbg() 67| 68| def simpanSbg(self): 69| filename = QFileDialog(self).filename: 64| self.editor.editor.

nama lenya dikosongkan. M sama besar. Courier yang bersifat xed. FILE DIALOG 76| fm = FormEditor() 77| app. Jika yaitu huruf texteditor4. hal yang biasa kita perlukan untuk mengedit Latihan texteditor4.py juga menyertakan perubahan font.maka tombol yang aktif adalah Baru dan Simpan Sebagai.1.20. Sebaliknya bila tidak terjadi perubahan . namun perlu ditingkatkan lagi faktor kenyamanan penggunaannya. tombol yang aktif hanyalah Buka. Keduanya mengembalikan nama le (QString) apabila tombol OK diklik. tidak. 2.misalnya setelah tombol Simpan di-klik . terutama berkaitan dengan tombol: 1.setMainWidget(fm) 78| app.py sudah memenuhi syarat untuk sebuah aplikasi text editor. Saat pertama kali program dijalankan. Petunjuk Gunakan setEnabled(). Bila ya maka ke empat tombol aktif. . Adanya status perubahan ( modied ) yang menunjukkan apakah ada perubahan pada editor sejak ia terakhir disimpan.exec_loop() 213 getOpenFileName() dan getSaveFileName() merupakan fungsi siap pakai untuk menampilkan le dialog. artinya ukuran huruf i dan suatu le teks.

yaitu adanya kemungkinan pemakai melakukan hal-hal yang menyebabkan hilangnya data pada saat seperti berikut ini: 1. Kali ini melibatkan faktor pengamanan data.214 BAB 20. Membuka le 3. Qt telah menyediakan Konrmasi ini berupa sebuah form yang berisi pertanyaan yang perlu dijawab. Menyimpan le dengan nama le yang sudah ada Oleh karena itu diperlukan suatu konrmasi terlebih dahulu sebelum hal-hal yang tidak diinginkan terjadi. icon ) sehubun- texteditor5. QMessageBox untuk kebutuhan tersebut dimana ia juga telah dilengkapi dengan gambar ( gan dengan pesan yang berada di dalamnya. Menutup aplikasi 2.2: Text Editor 20.2 Pesan & Konrmasi Penyempurnaan berlanjut terus. Memulai le baru 4.py -------------001| from qt import * 002| . FORM DIALOG Gambar 20.

setText( "Simpan Sebagai" ) 029| 030| self.showMaximized() .setAutoAdd(1) 009| panel = QFrame ( self ) 010| self.editor.setText ( "Baru" ) 026| btBuka.addStretch() 018| layout.editor.RightToLeft ) 019| 020| btSimpanSbg = QPushButton( panel ) 021| btSimpan = QPushButton( panel ) 022| btBuka = QPushButton( panel ) 023| btBaru = QPushButton( panel ) 024| 025| btBaru.setText ( "Simpan" ) 028| btSimpanSbg.setFamily("Courier") 013| self.setText ( "Buka" ) 027| btSimpan.font() 012| font.setCaption("Text Editor") 007| layout = QVBoxLayout( self ) 008| layout.setFont( font ) 014| 015| layout = QHBoxLayout( panel ) 016| layout.editor = QTextEdit( self ) 011| font = self.setDirection( QBoxLayout. PESAN & KONFIRMASI 215 003| class FormEditor(QWidget): 004| def __init__(self): 005| QWidget.20.__init__(self) 006| self.2.setFilename( None ) 031| self.setAutoAdd(1) 017| layout.

self.baru self.connect(btSimpanSbg.teksBerubah) def teksBerubah(self): self. self. self. SIGNAL("clicked()").connect(btBaru.simpan() return id == 1 def _simpan(self.warning( self. "Ya".buka self. filename=None): if filename: _filename = filename else : _filename = self.write( "%s" % self.216 BAB 20.text() ) f.simpanSbg) self. "Perhatian". "Kembali") if id == 0: return self.editor. FORM DIALOG 032| 033| 034| 035| 036| 037| 038| 039| 040| 041| 042| 043| 044| 045| 046| 047| 048| 049| 050| 051| 052| 053| 054| 055| 056| 057| 058| 059| 060| self.simpan) self.berubah: return 1 id = QMessageBox.connect( self.connect(btSimpan. SIGNAL("textChanged()"). self.connect(btBuka. "Tidak perlu". SIGNAL("clicked()"). SIGNAL("clicked()").berubah = 1 def lanjutkan(self): if not self. SIGNAL("clicked()").editor. self. "Simpan perubahan terlebih dahulu ?".close() . "w" ) f.filename f = open( _filename.

setText( "%s" % f.20.setFilename( _filename ) def simpan(self): if not self.berubah = 0 def baru(self): if not self.read() ) f.setFilename( None ) def buka(self): if not self.clear() self.editor. filename): self.berubah = 0 return 1 else: return self.2.getOpenFileName() if not filename.editor.close() self.filename: self.berubah: return if self.filename = filename self.simpanSbg() .isEmpty(): _filename = "%s" % filename f = open( _filename ) self.setCaption("Text Editor .filename) self.%s" % self.lanjutkan(): return filename = QFileDialog(self). PESAN & KONFIRMASI 061| 062| 063| 064| 065| 066| 067| 068| 069| 070| 071| 072| 073| 074| 075| 076| 077| 078| 079| 080| 081| 082| 083| 084| 085| 086| 087| 088| 089| 217 def setFilename(self._simpan() self.lanjutkan(): return self.

218 BAB 20.warning( self.exec_loop() . "Kembali") if id == 2: return if id == 0: tanya = 0 else: tanya = 0 _filename = "%s" % filename self.getSaveFileName() if filename.setMainWidget(fm) app. FORM DIALOG 090| 091| 092| 093| 094| 095| 096| 097| 098| 099| 100| 101| 102| 103| 104| 105| 106| 107| 108| 109| 110| 111| 112| 113| 114| 115| 116| def simpanSbg(self): if not self.exists( filename ): pesan="File %s sudah ada._simpan( _filename ) self.ignore() app = QApplication([]) fm = FormEditor() app.setFilename( _filename ) return 1 def closeEvent(self. "Jangan".berubah: return tanya = 1 while tanya: filename = QFileDialog(self).accept() else : e. Timpa ?" % filename id = QMessageBox.isEmpty(): return if QFile. e): if self.lanjutkan(): e. pesan. "Ya". "Perhatian".

py -------01| from qt import * 02| from string import 03| from locale import 04| import sys 05| 06| def cetak(s): 07| if sys. Berikut ini program kasir layak pakai dimana nama barang. upper setlocale.argv[1:]: 08| else: rjust. ljust. jumlah. input. Tidak ketinggalan nilai pembayaran- nya juga melalui class yang sama. INPUT QMessageBox Fungsi menyediakan fungsi (milik 219 warning() yang mengemba- likan nilai berupa nomor index tombol yang di-klik. QWidget) akan dipanggil pada e bertipe QCloseEvent yang memiliki fungsi accept() bermakna form ditutup dan ignore() yang berarti tidak jadi ditutup.3. LC_ALL.3 Input Bila dalam program Anda ada sebuah proses yang membutuhkan sebuah masukan saja. Anda dapat 20. saat form akan ditutup.20. serta harga satuannya dimasukkan menggunakan QInputDialog.argv[1] output = "/dev/lp0" . format output = sys. Fungsi ini menyertakan parameter closeEvent() Latihan Tambahkan fasilitas untuk mencetak. menggunakan perintah Linux cat namafile > /dev/lp0. maka QInputDialog adalah jawa- ban yang tepat.

nilai): n = format("%d". 8) s = "%s%s%s" % (a. QLineEdit. 27) b = rjust(n. FORM DIALOG 09| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| file = open(output. 20) b = rjust(j.getText("Kasir".220 BAB 20. 7) c = rjust(h. hrg. jml. "") total = 0 app = QApplication([]) while 1: nama. ok = QInputDialog.c) cetak(s) def cetakAkhir(nama. "Nama barang (Enter: Total."w") c = chr(15) + s + "\n" file.b) cetak(s) setlocale(LC_ALL. "") . jml. hrg): j = format("%. 1) a = ljust(nama[:20].b. nilai.2f".write(c) file. 1) a = ljust(nama.close() def cetakBrg(nama.Normal. Esc: Selesai)". 8) s = "%s%s" % (a. 1) h = format("%d".

subtotal) total = total + subtotal Siapkan printer.isEmpty(): t = format("%d". dan jalankan program ini: $ python input. total) cetakAkhir("BAYAR". masukkan nama le pengganti: . ok = QInputDialog. "Harga satuan") if ok: subtotal = round(hrg * jml) cetakBrg(nama. 9999999.3. 2) if ok: hrg. jml.getDouble(nama. 1. kembali) c = "\n" * 5 cetak(c) total = 0 else: nama = upper("%s" % nama) jml. bayar) cetakAkhir("KEMBALI".getInteger(nama. ok = QInputDialog. 0.py namun bila printer tidak ada. "Pembayaran (Total Rp %s)" % t. ok = QInputDialog.20. INPUT 38| 39| 40| 41| 42| 43| 44| 45| 46| 47| 48| 49| 50| 51| 52| 53| 54| 55| 56| 57| 58| 59| 60| 61| 221 if not ok: break if nama. total) if ok: kembali = bayar . 1) bayar. "Jumlah barang".getInteger("Kasir".total cetakAkhir("TOTAL". total.

label. FORM DIALOG $ python input.222 BAB 20. nilai="") getInteger(caption. terkecil=-214748364. dan oat: getText(caption. mode. desimal=1) . integer. label.py /tmp/kasir. label.txt QInputDialog memiliki tiga fungsi untuk Pada contoh di atas memperoleh nilai string. nilai=0. nilai=0) getDouble(caption. terbesar=214748364.

OpenOce. Contohnya: StarOce. 2. dst. sangat mirip dengan pada aplikasi qtable1. Jumlah baris ditentukan dari sumber data. 3. 223 . Sumber data berupa list dua dimensi sebagai perwujudan dari struktur tabel. Qt telah menyediakan class Sifat QTable QTable yang terdapat pada modul qttable.py memberikan contoh sederhana penggunaan QTable.Bab 21 Tabel Tabel merupakan daftar yang terdiri dari baris dan kolom. Jumlah kolom ditentukan dari daftar judul kolom. sheet yang bisa kita jumpai Adapun penjelasan yang ingin disampaikan adalah: 1. 1 Spreadsheet merupakan aplikasi yang sering digunakan dalam aplikasi oce. KOce. spreadsheet 1 .

5. "Bogor" ] 13| ] 14| self. 11| [ "Ahmad".setNumCols( len(kolom) ) 16| self.setNumRows( len(isi) ) 17| i = -1 2 Cell: elemen pada QTable . "Purwokerto" ]. TABEL Gambar 21.setCaption("Table") 08| kolom = [ "Nama". "Alamat" ] 09| isi = [ 10| [ "Pribadi Endro". Bagaimana mengambil nilai dari qtable1.t.1: QTable 4. "Kemayoran" ].t = QTable(self) 15| self.__init__(self) 07| self. Bagaimana mengisi nilai pada cell. 12| [ "Putera Sinaga".2 cell.py ---------01| from qt import * 02| from qttable import QTable 03| 04| class FormTable(QWidget): 05| def __init__(self): 06| QWidget.t.224 BAB 21.

row.setText( b.t. self.text( row.t.connect( self. nilai ) self.t.setLabel( i. judul ) b = -1 for brs in isi: b = b + 1 k = -1 for nilai in brs: k = k + 1 self.t. col ) ) app = QApplication([]) fm = FormTable() app.exec_loop() QTable yang digunakan adalah: Penjelasan mengenai fungsi setNumCols() setNumRows() menentukan jumlah kolom.int)"). col): self. SIGNAL("currentChanged(int.show() self.225 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| for judul in kolom: i = i + 1 self.setMainWidget(fm) app.k. .horizontalHeader().setCaption( self.posisiBerubah ) def posisiBerubah(self. menentukan jumlah baris.

1 Mengubah Sifat Untuk berbagai keperluan kita perlu mengubah sifat QTable dengan membuat class baru sebagai keturunannya. current cell 3 mendapatkan teks pada cell tertentu. Pada kasus isi cell terlalu panjang namun Anda hanya ingin mengubah sedikit saja maka tombol ini sangat berguna. QTable mengizinkan pemakai untuk mengubah- ubah isi. Untunglah QTable memiliki banyak fungsi yang memungkinkan perubahan 3 Current cell: cell yang sedang fokus. Escape membatalkan perubahan 21. sinyal yang muncul pada saat currentChanged() Secara default berubah. horizontalHeader() QHeader.226 BAB 21. Beberapa tombol keyboard berikut ini juga dapat Anda gunakan: F2 isi cell siap diubah. dan lebar kolom pada saat runtime. . TABEL mendapatkan objek header (judul kolom) yang bertipe tentu. lebar baris. Fungsi setLabel()-nya di- gunakan untuk memberikan judul pada kolom ter- setText() text() mengisi teks pada elemen ( cell ) tertentu.

Salah satu perubahan yang dimaksud adalah pada penggunaan tombol keyboard berikut ini: Insert Down menyisipkan baris menambah baris bila baris aktif ( da di baris terakhir. Sehingga dikatakan bahwa kolom paling kiri belum tentu merupakan kolom pertama.1. . MENGUBAH SIFAT saja 227 sifat ini dilakukan dengan mudah. Delete menghapus isi cell current row ) bera- Ctrl-Delete menghapus baris Home menuju kolom paling kiri yang tampak aktif (current row) End menuju kolom paling kanan yang tampak pada baris aktif Ctrl-Home menuju baris pertama dan kolom paling kiri yang tampak (kiri atas) Ctrl-End menuju baris pertama dan kolom paling kanan yang tampak (kanan bawah) Selain itu ada beberapa sifat lainnya yang ditambahkan: 4 pada baris 4 Kolom bisa disembunyikan dengan perintah setHide().21. Class tersebut kita namakan Grid. Kolom seperti ini dihindari sebagai kolom aktif (current column ).

. Penekanan tombol Enter setelah mengubah nilai cell akan mengarahkan kursor ke kanan. Bahkan penekanan tombol Down juga akan menambah baris.numCols()-1: 5 focus widget: objek aktif yang siap menerima input atau aksi lainnya. focus widget.__init__(self. Pada agar tampak 1.py ------01| from qt import * 02| from qttable import QTable 03| 04| class Grid(QTable): 05| def __init__(self. QTable tidak memiliki sarana untuk menambah baris se- cara langsung. 4.5 QTable tidak menunjukkan Pada form yang memiliki widget lebih dari satu tentu saja bisa membin- focus -nya. Pada Grid penekanan tombol Insert akan menyisipkan baris. Grid minimal terdapat satu baris 2. parent): 06| QTable. parent) 07| self. TABEL bahwa dirinya merupakan gungkan pemakai. 3. Pada saat tidak ada baris. Penambahan baris baru mengarahkan kursor ke kolom paling kiri agar memudahkan pengisian.setNumRows(1) 08| 09| def activateNextCell(self): 10| if self.currentColumn() < self.228 BAB 21. grid.

row) else: for col in range( self.currentRow().numRows() > 1: QTable.1 self.setCurrentCell( self.setCurrentCell( r.setCurrentCell( row.numRows(): r = self.currentColumn()+1) def setNumRows(self. count): if count > 1: c = count else: c = 1 QTable. MENGUBAH SIFAT 11| 12| 13| 14| 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39| 229 self.numRows() ) else: self. count) self.currentRow() == self.numRows() .21.setNumRows(self. count=1): QTable.numCols() ): self.currentColumn() ) def sisip(self): self. self.setCurrentCell(self.clearCell( row. row): r = self.insertRows(self. self. c) def insertRows(self.insertRows( self.numRows()-1: self. self. .removeRow(self.currentRow()+1. row. row.insertRows( self.currentRow() ) def turun(self): if self.kolomKiri() ) def removeRow(self. col ) if r == self.currentRow() if self.1.

removeRow( self.currentColumn() ) def hapusCell(self): self.columnWidth(col) == 0: if col == self.currentRow(). self.kolomKiri() ) def palingKiri(self): self.setCurrentCell( self.currentRow() ) def kolomKiri(self): col = 0 while self.currentColumn() ) def hapusBaris(self): self.currentRow(). self.setCurrentCell(0.columnWidth(col) == 0: if col == 0: return col col = col .kolomKiri() ) .1 return col def kiriAtas(self): self.numCols()-1 while self. self.clearCell( self.numCols()-1: return col col = col + 1 return col def kolomKanan(self): col = self. TABEL 40| 41| 42| 43| 44| 45| 46| 47| 48| 49| 50| 51| 52| 53| 54| 55| 56| 57| 58| 59| 60| 61| 62| 63| 64| 65| 66| 67| 68| self.230 BAB 21.

turun() 82| elif e. 72| self.21.numCols() == 0: return 80| elif e. e) 92| 93| if __name__ == "__main__": 94| app = QApplication([]) 95| fm = Grid(None) 96| fm.key() == Qt.state() == Qt.ControlButton: self.numRows()-1.kolomKanan() ) 73| 74| def palingKanan(self): 75| self.palingKanan() 91| else: QTable.palingKiri() 88| elif e.kiriAtas() 87| else: self.Key_Home: 86| if e.ControlButton: self. e): 79| if self.key() == Qt.setCurrentCell( self.currentRow().Key_Delete: 83| if e.key() == Qt.Key_Down: self.setCurrentCell( self.hapusCell() 85| elif e.hapusBaris() 84| else: self.key() == Qt.kolomKanan() ) 77| 78| def keyPressEvent(self.1.show() .Key_End: 89| if e.key() == Qt.keyPressEvent(self.setNumCols(5) 97| fm.state() == Qt.ControlButton: self.kananBawah() 90| else: self.state() == Qt. MENGUBAH SIFAT 231 69| 70| def kananBawah(self): 71| self.Key_Insert: self.sisip() 81| elif e. 76| self.

setMainWidget(fm) app. Fungsi setCurrentCell() keyPressEvent() ini berpengaruh pada nilai currentRow() dan currentColumn(). Saat ini ditandai . 6 Edit-mode: saat suatu cell sedang diubah isinya.232 BAB 21. dipanggil saat tombol pada keyboard ditekan dimana cell tidak sedang di-edit (tidak berlaku pada saat edit-mode). TABEL 98| 99| app. menghapus baris namun tetap memastikan Grid memiliki setidaknya satu baris.setidaknya . dengan adanya editor (QLineEdit) pada cell. mengarahkan kursor ke cell tertentu. menyisipkan baris dan menempatkan kursor di kolom paling kiri.exec_loop() QTable yang ditulisulang (reimplementation ): Grid memiliki satu baris.memi- liki satu baris. menghapus isi cell. Berikut ini fungsi __init__() memastikan activateNextCell() setNumRows() insertRows() removeRow() clearCell() dipanggil saat pemakai menekan Enter setelah selesai mengubah isi cell (edit-mode diubah sifatnya agar 6 berakhir) Grid .

contoh: 2.2 Bentuk Tampilan Berkaitan dengan angka biasanya kita dihadapkan pada masalah tampilan seperti rata kanan.340. 2. Struktur data disimpan dalam list dua dimensi yang mencerminkan bentuk tabel. pemisah ribuan. paintCell() perlu ditulis ulang agar data ditampilkan dengan bentuk yang diinginkan. Pemisah ribuan menggunakan karakter titik. integer. Pemisah pecahan menggunakan karakter koma.2: ValueGrid 233 21. QTable memiliki fungsi paintCell() yang memang bertugas untuk menampilkan tulisan. BENTUK TAMPILAN Gambar 21.234. Kita akan membuat sebuah class baru bernama sebagai berikut: 1. Tipe data elemennya bisa string.21. ValueGrid yang merupakan keturunan class Grid sebelumnya dengan ciri . 6. Float ditampilkan dengan dua angka pecahan. contoh: 9.25. atau oat. 3. 5. atau jumlah angka dibelakang koma pada bilangan pecahan.2. 4. Integer dan oat ditampilkan rata kanan dan disertai pemisah ribuan.

Karena ini bisa dianggap sebagai fungsi umum. 7. Sehingga string =80*5 akan ditampilkan angka 40.py --------01| import string 02| import locale 03| from math import * 04| 05| locale.234 BAB 21. fungsi.setlocale(locale. Meniru spreadsheet. TABEL koma maupun titik. bukan hasilnya. "") 06| 07| . Baris aktif ( current row ) diterangi (highlight ). Sebelumnya akan kita buat dulu dua buah fungsi pendukung yaitu gkan angka() dan ribu().LC_ALL. Fungsi exec() digunakan untuk menerjemahkannya. 9. yang penulisannya perlu diawali dengan karakter samadengan (=). maka sebaiknya kita letakkan keduanya dalam suatu modul. ValueGrid juga mengenal bentuk ru- mus matematika. angka() menerima masukan bertipe apa saja yang akan menerjemahkannya menjadi bilangan. Sedan- ribu() menerima masukan berupa bilangan integer atau oat dan mengembalikan string dari bilangan tersebut dalam bentuk sebagaimana pembahasan sebelumnya. Namun yang tersimpan dalam struktur data tetap string tersebut. Input untuk bilangan pecahan bisa menggunakan pemisah 8.

replace(a.format( "%d".21. 1 ) else: return "" """ Mengubah string menjadi angka.format( "%. BENTUK TAMPILAN 08| 09| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 235 """ Mengubah angka menjadi string dengan format ribuan.". n. """ def ribu(n): if type(n) == type(0): return locale.". Membolehkan rumus matematika. 1 ) elif type(n) == type(0.2f". Membolehkan pemisah pecahan dengan koma.".") try: return int(a) except ValueError: try: return float(a) except ValueError: if a and a[0] == "=": try: exec("a"+a) return a except: .strip("%s" % s) a = string.2. """ def angka(s): a = string. n.0): return locale.

penText = QPen() 012| self. parent) 009| self.int)" 020| self.connect(self.brushCurrent = QBrush() 014| self.setStyle( QBrush. SIGNAL("currentChanged(int._row = 0 # baris terakhir sebelum currentRow( 018| self.py yang selain dapat Modul ini digunakan dalam untuk mencoba.saatPindah) 021| . parent): 008| Grid.setColor( QColor("black") ) 013| self. TABEL 37| return valuegrid.penBox = QPen() 010| self.penText.beforeDelete = None # sebelum data dihapus 019| self.__init__(self.data = [] 017| self.setColor( QColor("lightgray") ) 011| self.penBox.py -----------001| from qt import * 002| from qttable import QTable 003| from grid import Grid 004| from fungsi import angka.brushCurrent.236 BAB 21.brushCurrent.SolidPattern ) 016| self.setColor( QColor("yellow") ) 015| self. sebagai modul juga dapat dijalankan sebagai program utama valuegrid. ribu 005| 006| class ValueGrid(Grid): 007| def __init__(self.

beforeDelete: self.data = data self. data): if data: self. count=1): if not self. count) def insertRows(self.setNumRows( len(data) ) else: self. count): self.repaintContents() def setNumCols(self.21. self. row.beforeDelete(row) . BENTUK TAMPILAN 022| 023| 024| 025| 026| 027| 028| 029| 030| 031| 032| 033| 034| 035| 036| 037| 038| 039| 040| 041| 042| 043| 044| 045| 046| 047| 048| 049| 050| def resizeData(self.setCurrentCell( 0.barisKosong ) for i in range(count): self.currentColumn() ) self.data: if self.append( self.barisKosong = [] for i in range( count ): self.barisKosong.data: self.data.insertRows(self. count) def removeRow(self.insert( (row. i): pass # hemat memory 237 def setData(self. list(self.data.barisKosong)) ) Grid. row): if self. row.append("") QTable.2.setNumRows(1) self.data = [] self.setNumCols(self.

row. col. row) def createEditor(self.238 BAB 21.text() if s and s[0] != "=": a = angka(s) if a: s = a if not self.data[row][col] = "" self.data[ row ] Grid.barisKosong) ) self. row. TABEL 051| 052| 053| 054| 055| 056| 057| 058| 059| 060| 061| 062| 063| 064| 065| 066| 067| 068| 069| 070| 071| 072| 073| 074| 075| 076| 077| 078| 079| del self. selected): align = QPainter.data[row][col] a = angka(d) if a: .data[row][col] = s def clearCell(self.data: self.setText("%s" % self.removeRow(self. col.RTL if self. painter. row.data. col): if self.data: self. col) def paintCell(self.append( list(self.cellWidget( row.data[row][col]) return e def setCellContentFromEditor(self. col): s = "%s" % self.data and initFromCell: e. row.data: d = self. initFromCell): e = QLineEdit(self) if self. col ).updateCell(row. cr.

BENTUK TAMPILAN 080| 081| 082| 083| 084| 085| 086| 087| 088| 089| 090| 091| 092| 093| 094| 095| 096| 097| 098| 099| 100| 101| 102| 103| 104| 105| 106| 107| 108| 239 s = ribu(a) align = QPainter. self.height()-1 ) painter.setRight( self.setRight( self. cr.height()-1.penText ) painter. cr.data: painter.width()-1.width(). cr.repaintContents(r) r = self.setPen( self.drawText(2. row. cr. 0 ) r. cr.width().2. cr.21._row: r = self.0.width()-1.width() ) self.width().width() ) self._row.width()-4.repaintContents(r) self.brushCurrent ) else: painter.0. cr.height()-1.fillRect( 0. cr. col): if row != self. align. cr. cr. 0 ) r.height() ) painter.height()-4.height(). s) def saatPindah(self.drawLine( 0.LTR else: s = d else: s = "" if row == self.penBox ) painter.setPen( self.cellGeometry( self.eraseRect( 0.drawLine( cr. cr. 0 ) painter._row = row .2.cellGeometry( row.currentRow() and self.

115| [1287.0"."Kg" ] ] 116| fm. juga menggambar kotak. ."Jeruk"."Belimbing".3000.setNumCols(4) 117| fm.240 BAB 21.show() 119| app. memastikan jumlah baris data sesuai dengan jum- lah baris yang tampak. setNumCols() insertRows() removeRow() penyiapan list berupa baris kosong untuk mem- percepat penambahan baris (record). alasannya sama dengan insertRows().setMainWidget(fm) 120| app. ValueGrid pass menyiapkan struktur data internal QTable.0. menyiapkan struktur data tabel berupa list dua QPen untuk menulis teks dan resizeData() na ri."Kg"].setData(data) 118| fm. Kare- memiliki struktur data sendiri maka fungsi ini tidak diperlukan guna menghemat memoberarti tidak melakukan apa-apa.exec_loop() Adapun fungsi yang ditulisulang adalah: ___init__() dimensi (data). TABEL 109| 110| 111| if __name__ == "__main__": 112| app = QApplication([]) 113| fm = ValueGrid(None) 114| data = [ [1001."=7000+500.

Misalnya saat tion form di- minimize lalu di-maximized. Fungsi ini harus Standarnya ada- nakan untuk memasukkan data. 7 setCellContentFromEditor() dipanggil usai edit-mode. Fungsi cellWidget() digunakan untuk men- dapatkan widget yang dimaksud. initFromCell bernilai logika yang apabila true berarti tombol F2 ditekan.2. clearCell() mengganti elemen data dengan string hampa se- bagai perwujudan proses penghapusan data. dan tentunya Anda dapat meng- gunakan widget lainnya sesuai dengan kebutuhan. QLineEdit. ReimplementaValueGrid memileluhurnya. Fungsi ini menyer- ini perlu dilakukan karena liki struktur data sendiri yang tidak dikenal oleh fungsi paintCell() takan beberapa variabel yang berguna dalam pros- 7 Lihat halaman 157 mengenai penggunaan tombol ini. updateCell() paintCell() memanggil paintCell() untuk memperbaharui tampilan pada cell tertentu. Sesuai namanya fungsi ini bisa juga dikatakan sebagai pembuat widget.21. BENTUK TAMPILAN createEditor() lah 241 mengembalikan (return) widget yang akan digu- dipanggil menjelang edit-mode. . sehingga ini saat yang tepat untuk mengisi data sesuai dengan isi widget tersebut. merupakan event yang terjadi saat ada perin- tah untuk menggambar cell tertentu. Sam- pai disini widget yang dibuat createEditor() belum dihapus dari memori.

242 BAB 21. Untuk mendapatkan area tersebut berdasarkan nomor QPen Merupakan pena gambar yang dipakai QPainter. TABEL es penggambaran. paintCell() ( lah fungsi repaintContents() yang otomatis akan memanggil paintCell() sesuai dengan area yang sudah ditentukan. QBrush Merupakan cat yang dipakai pada latar belakang ( background ). Fungsi setColor() pada contoh di atas digunakan untuk menentukan warnanya. repaintContents() tanpa nilai masukan berarti menggambar ulang seluruh area QTable. balikan nilai bertipe kursor. QRect. highlight ) pada baris sebelumnya. leluhur QTable. (QRect painter bertipe QPainter yang bertugas menggambar cell yang terletak pada 8 ). baris tidak dipanggil untuk menghilangkan efek terang Oleh karena itu digunakan- sebelum dan sesudah kepindahan QTable memiliki fungsi cellGeometry() yang akan mengemQRect. QPainter untuk memberi corak Fungsi setColor()-nya un- 8 Lihat halaman 168 tentang . Fungsi ini sebenarnya milik QScrollView. Pada saat kursor pindah ke cell lain di baris yang berbeda. selected cr bernilai logika yang apabi- la true berarti kursor berada pada cell di baris kolom col row (sedang fokus). Area yang dimaksud adalah baris.

sedangkan bisa diterapkan: 243 setStyle() untuk menen- tukan pola dalam pengecatan. kepadatan 37%.21. SolidPattern Dense1Pattern Dense2Pattern Dense3Pattern Dense4Pattern Dense5Pattern Dense6Pattern Dense7Pattern HorPattern VerPattern garis horizontal. BENTUK TAMPILAN tuk menentukan warna cat. garis miring ke kiri ( \ ). kotak-kotak. garis vertikal. kepadatan 88%. kepadatan 6%. Berikut ini beberapa pola yang NoBrush tidak menggunakan cat (default). kepadatan 63%.2. kepadatan 94%. kepadatan 12%. CrossPattern BDiagPattern FDiagPattern DiagCrossPattern . belah ketupat. kepadatan 50%. garis miring ke kanan ( / ). kepadatan 100%.

244 BAB 21. pada contoh di atas adalah: fillRect() mengecat bidang tertentu. setY(). menghapus bidang tertentu. QRect Merupakan denisi suatu kotak dalam bidang gambar ( shape ). panjang kotak. eraseRect() setPen() menentukan pena (QPen) untuk menggambar. membuat tulisan. Untuk mengubahnya gunakan koordinat dari atas. TABEL Fungsi yang digunakan QPainter Merupakan alat gambar pada widget. setWidth(). Untuk mengubahnya gunakan setHeight(). Untuk mengubahnya gunakan lebar kotak. Untuk mengubahnya gunakan . Fungsi ini memiliki parameter drawLine() drawText() masukan align yang menentukan apakah tulisan ditampilkan rata kiri (RTL) atau rata kanan (LTR). setX(). Denisi yang dimaksud seperti posisi dan ukuran berikut ini: x() y() height() width() koordinat dari kiri. membuat garis.

setRight().3 Form Pencarian Form Pencarian adalah form yang digunakan sebagai alat untuk mencari kata tertentu dalam suatu kolom tabel. sama dengan Untuk mengubahnya gunakan koordinat atas. maka akan dicari nama barang yang mengandung kata KAPAL. maka kursor akan mengarah pada baris dimana terdapat nama barang yang diawali KAPAL atau misalnya Kapal (sama saja). Namun apabila tidak ditemukan. Form ini memiliki tur sebagai berikut: 1. Form Pencarian akan menggunakan kolom nama sebagai tempat pencarian. x(). Pencarian berdasarkan nama dan tidak membedakan huruf kecil maupun besar. sama dengan bahnya gunakan left() + width(). sukkan. 21. y(). Untuk mengubah- koordinat kanan. Kita ambil contoh sebuah tabel barang yang memuat nama barang dan harganya. Sampai di sini pencarian bisa dilanjutkan dengan . Untuk mengu- setTop(). koordinat bawah. FORM PENCARIAN left() right() top() bottom() koordinat kiri. setBottom().3. sama dengan Untuk mengubahnya gunakan top() + height().21. Terdapat dua widget utama: teks yang dicari dan QLineEdit untuk menuliskan ValueGrid sebagai tabelnya. Misalkan kata KAPAL dima- 2. sama dengan nya gunakan 245 setLeft().

6500 semangka tanpa biji. Apabila tidak ditemukan juga.3000 rambutan rapiah. 4. Tombol Enter digunakan untuk menutup form sekaligus menyatakan bahwa barang telah dipilih sesuai dengan yang ditunjuk kursor. 5.4000 anggur merah.5500 rambutan binjai.9000 mangga indramayu.5000 duku. TABEL menekan tombol Ctrl-PageDown.3000 semangka kuning. Penekanan tombol Esc akan menghapus kata yang dicari.7000 jeruk medan. Bermanfaat manakala form ini dipakai oleh form lain sebagai alat bantu pencarian barang. dan bisa juga berfungsi untuk menutup form apabila memang tidak ada yang dihapus.6000 durian monthong. Sebagai sumber data akan kita gunakan le teks dengan contoh seperti di bawah ini: Nama.10000 alpukat. maka akan ditampilkan pesan.20000 .246 BAB 21.Harga mangga harum manis. 3. Navigasi untuk perpindahan kursor menggunakan tombol panah atas atau panah bawah.

12000 pir shandong.10000 lengkeng lokal. tuk menangani le ini akan dibuatkan sebuah class bernama TableFile. Data boleh ditulis dengan huruf kecil maupun besar karena nanti semuanya akan ditampilkan dengan huruf besar secara urut berdasarkan kolom pertama.15000 lengkeng impor. pemisah antar eld menggunakan karakter titik koma (.21.). Baris pertama merupakan Unjudul kolom dan baris berikutnya merupakan datanya.9000 247 Seperti terlihat pada contoh di atas.8000 jeruk pakistan. upper linecase import LineCase halaman 94.py ------001| from 002| from 003| from 004| from 005| 9 Lihat qt import * valuegrid import ValueGrid string import splitfields.3. FORM PENCARIAN anggur hijau. strip. .5000 mangga gedong.15000 jeruk lokam. cari.10000 mangga golek. modul Program ini menggunakan linecase9 untuk memastikan kata yang dicari ditulis dengan huruf besar.7000 pir australia.

e): 025| if e.addWidget(self.state() == Qt.teks) 014| layout.tabel.text(). TABEL 006| class FormCari(QDialog): 007| def __init__(self.horizontalHeader().Upper) 012| self.Key_Escape: self. 008| kolomCari=0): 009| QDialog.key() == Qt.clear() . data.Key_Return.isEmpty(): self.teks.tabel.reject() 034| else: self.lanjut() 030| else: self.ControlButton and \ 029| e.addWidget(self.escape() 026| elif e.keyPressEvent( e ) 031| 032| def escape(self): 033| if self. parent.Key_PageDown: self.key() == Qt. labels=[].teks.key() in [Qt.teksBerubah = self. parent) 010| layout = QVBoxLayout(self) 011| self.tabel.tabel.setNumCols( len(labels) ) 016| i = -1 017| for label in labels: 018| i = i + 1 019| self.teksBerubah 023| 024| def keyPressEvent(self.Key_Enter]: 027| self.tabel = ValueGrid(self) 013| layout.teks.setData( data ) 021| self.label) 020| self.__init__(self. Qt.tabel) 015| self.setLabel(i.teks = LineCase(self.kolomCari = kolomCari 022| self.248 BAB 21. LineCase.accept() 028| elif e.

tabel.find(s) > -1 051| if ketemu: 052| if self.setCurrentCell(brs.teks.kolomCari] 048| t = QString(data).cari(0) < 0: 038| QMessageBox. awalan=1.tabel.tabel.text()) 040| 041| def cari(self.cari(0) 061| 062| 063| """ TableFile .tabel. "Perhatian".warning(self. self.currentRow() != brs: 053| self. FORM PENCARIAN 249 035| 036| def teksBerubah(self.numRows()-1: 046| brs = brs + 1 047| data = self.21.upper() 043| brs = mulaiBaris 044| ketemu = 0 045| while brs < self.isEmpty(): return 059| if self.text(). 039| "%s tidak ditemukan" % w. self.upper() 049| if awalan: ketemu = t.data[brs][self.text(). mulaiBaris=-1): 042| s = "%s" % self.3.teks.cari(0.tabel.currentRow() ) < 0: 060| self.cari() < 0 and self.find(QRegExp("^"+s)) > -1 050| else: ketemu = t. w): 037| if self.kolomCari) 054| return brs 055| return -1 056| 057| def lanjut(self): 058| if self.

lines[0] 082| self.sort() 089| self.labels = splitfields(strip(labels). self.lines = f. TABEL 064| """ 065| class TableFile: 066| def __init__(self.readlines() 077| f.updateLines() 071| self.datalines = self. filename.updateRecords(uppercase.filename = filename 069| self.250 BAB 21.pemisah) 092| rec = [] .lines[1:] 086| 087| def updateRecords(self.updateStructure() 072| self.datalines: 091| fields = splitfields(line. 083| self.records = [] 090| for line in self. sort) 073| 074| def updateLines(self): 075| f = open(self. uppercase=0.".datalines. pemisah=". 067| uppercase=1.close() 078| 079| def updateStructure(self): 080| # Baris pertama judul kolom 081| labels = self.filename.pemisah) 084| # Baris berikutnya data 085| self.pemisah = pemisah 070| self. sort=0): 088| if sort: self. sort=1): 068| self."r") 076| self.

3.setColumnWidth(0.csv maka perintah untuk menjalankan program ini adalah: . t.tabel.exec_loop() 115| if fm.data[row][col] Misalkan sumber data disimpan dalam le barang.currentRow() 117| col = fm.showMaximized() 114| fm.argv[1] 108| t = TableFile( filename ) 109| 110| app = QApplication([]) 111| fm = FormCari(None.200) 113| fm.tabel.tabel.tabel.result() == QDialog.records.Accepted: 116| row = fm.records.21.labels) 112| fm.append(n) 102| self.currentColumn() 118| print fm.append( rec ) 103| 104| 105| if __name__ == "__main__": 106| import sys 107| filename = sys. t. FORM PENCARIAN 251 093| for field in fields: 094| n = strip(field) 095| if uppercase: n = upper(n) 096| try: 097| n = float(n) 098| if n == int(n): n = int(n) 099| except ValueError: 100| pass 101| rec.

Masukan pertamanya adalah nomor in- dex kolom. Yang penting data tersebut dikonversi ke bentuk list dua dimensi (struktur tabel). Pada program di atas digunakan untuk mencari awalan kata tertentu. keyPressEvent() Perhatikan memanggil event serupa milik meski kursor berada pada erapkan tombol-tombol tabel (ValueGrid).py barang.csv FormCari sebenarnya membe- Terlepas dari sumber datanya. find() dapat menerima masukan berupa regular expression 10 (QRegExp). misalnya Praktis lebih menghe- yang didalamnya terdapat baris yang navigasi perpindahan current record. mindahkan fokus ke mat waktu karena tidak harus menekan tombol Tab untuk me- tabel. dan yang kedua merupakan lebar kolom dalam Form ini mengoptimalkan penggunaan event. TABEL $ python cari. Perhatikan karakter pangkat (^) di awal string. baskan bentuk penyimpanan data.252 BAB 21. 10 Regular expression: ekspresi untuk pencocokan pola. event pixel. tertentu pada setColumnWidth() digunakan untuk menentukan lebar kolom QTable. Ini artinya teks (LineCase) namun dapat menfungsi yang dimiliki tabel. Untuk mencari kata digunakanlah fungsi find() pada QString. .

1 Lihat 2 Lihat halaman 119.Bab 22 Kasir II Kasir II merupakan aplikasi kasir yang memiliki tur lebih ketimbang pendahulunya. 2. halaman 168.2 cari. Mudah perawatan dimana daftar barang disimpan dalam le teks biasa sebagaimana yang digunakan 3. Bila teks yang dimasukkan berupa angka maka tidak dilakukan pencarian. 253 . Metode pencarian dan tombol navigasi masih sama dengan leluhurnya. Kasir I . Form-nya merupakan turunan dari 1 FormCari pada cari. Fitur yang dimaksud adalah adanya daftar harga barang. Berikut ini tur dari Kasir II: 1. 4.py.py.

py --------01| from qt import * 02| from cari import FormCari 03| from fungsi import ribu 04| from string import rjust. Tombol Enter atau Return digunakan untuk pembayaran. output="/dev/lp0"): . KASIR II Nilainya diambil dari teks pada poin 4. kasir2. t. Adapun bentuk struknya hampir mirip dengan yang dihasilkan Kasir I. Terdapat label yang menampilkan total transaksi. 7.000 263.25 150.750 5.000 36.65 113. ljust 05| 06| class FormKasir(FormCari): 07| def __init__(self. 6. Sifat pencatatan transaksi masih mirip Kasir I yaitu langsung ke printer atau bisa juga ke sebuah le.250 Jadi secara umum Kasir II masih menyimpan sifat kesederhanaan Kasir I yaitu kemudahan instalasi dan perawatan. parent.750 300. 5.254 BAB 22. tentunya dengan informasi yang lebih lengkap: RAMBUTAN BINJAI ANGGUR MERAH TOTAL BAYAR KEMBALI 30-01-03 00:42 50.

teks.insertWidget(0.__init__(self. self.teksBerubah(self. e) def escape(self): self.lcd.clear() def teksBerubah(self.Key_Enter]: if not self.total = 0 self. w): s = "%s" % w. t.Flat ) self.records."w") def keyPressEvent(self. Qt. t.setCaption("Kasir II") self.setSegmentStyle( QLCDNumber.lcd) self.keyPressEvent(self.lcd = QLCDNumber(self) self.labels.300) self.Key_Return.text() try: n = int(s) except ValueError: FormCari. w) def beli(self): row = self.setColumnWidth(0.layout().file = open(output.tabel.lcd.bayar(): self.tabel.setMinimumHeight(150) self.setNumDigits(10) self.key() in [Qt.lcd. 0) self. e): if e.beli() else: FormCari. parent.255 08| 09| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| FormCari.currentRow() .

clear() self.total) ) self. 0.data[row][0] harga = self.s) ) self.selectAll() def bayar(self): s = "%s" % self.cetakAkhir("KEMBALI".data[row][1] jml. bayar) self. 2) if ok: subtotal = int(jml * harga) self.total = 0 return 1 def cetak(self. subtotal) self.cetakAkhir("TOTAL".total = self.self.teks.text() try: bayar = int(s) except ValueError: return kembali = bayar . ok = QInputDialog.lcd.toString( "dd-MM-yy hh:mm") s = "\n" * 5 self. s): .tabel. 1. kembali) w = QDateTime.total) self. 99999.teks.total + subtotal self. jml.cetak( "%s%s" % (w.teks.lcd.currentDateTime().256 BAB 22.total self. "Sebanyak". self. KASIR II 37| 38| 39| 40| 41| 42| 43| 44| 45| 46| 47| 48| 49| 50| 51| 52| 53| 54| 55| 56| 57| 58| 59| 60| 61| 62| 63| 64| 65| nama = self.display( ribu(kembali) ) self.cetakBarang(nama.cetakAkhir("BAYAR".display( ribu(self.getDouble(nama.tabel.

_jml.10) 78| _total = rjust(ribu(total). _total) 80| self.argv[2] 90| else: output = "/dev/lp0" 91| app = QApplication([]) 92| fm = FormKasir(None.argv[2:]: output = sys.257 66| self.exec_loop() .cetak(s) 75| 76| def cetakAkhir(self.file.write(chr(15)+s) 67| self. 7) 72| _subtotal = rjust(ribu(subtotal).cetak(s) 81| 82| 83| if __name__ == "__main__": 84| import sys 85| from cari import TableFile 86| 87| filename = sys. _subtotal) 74| self.8) 73| s = "%s%s%s\n" % (_nama. nama.25) 79| s = "%s%s\n" % (_nama.showMaximized() 94| fm. subtotal): 70| _nama = ljust(nama[:20]. nama.flush() 68| 69| def cetakBarang(self.file. jml. t. total): 77| _nama = ljust(nama. output) 93| fm.argv[1] 88| t = TableFile( filename ) 89| if sys. 20) 71| _jml = rjust(ribu(jml).

258

BAB 22. KASIR II
cari.py: $ python kasir2.py barang.csv

Cara menggunakannya mirip dengan

dimana

barang.csv adalah sumber data harga barang.

lupa, pastikan status printer dalam keadaan siap ( ka tambahkan nama lenya:

ready ).

Jangan

Apabila Anda ingin menyimpan transaksi ke sebuah le ma-

$ python kasir2.py barang.csv /tmp/kasir.txt
Perlu diketahui pula bahwa le tersebut akan dikosongkan terlebih dahulu manakala program dijalankan kembali. Jadi penyimpanannya tidak permanen. Anda juga bisa menggunakan

/dev/null

bila transaksi tidak ingin disimpan:

$ python kasir2.py barang.csv /dev/null

Bab 23

Database
Database merupakan penyimpan data yang terpisah dari program. File database, atau lebih tepatnya

barang.csv sebelumnya juga bisa dikatakan sebagai

database server , yaitu suatu program yang dirancang khusus untuk menyimini database yang dimaksud adalah menggunakan pan dan mengolah data. Untuk menggunakan produk database tertentu dalam program, dibutuhkan suatu

database le.

Sedangkan pada bab

driver

sebagai penghubungnya.

Qt

memiliki beberapa driver untuk PostgreSQL, MySQL, Oracle, Sybase, MS-SQL, ODBC, dsb. berkaitan dengan database ini berada dalam modul

1 Pada Qt kumpulan class yang

qtsql.

Adapun tahapan yang biasa terjadi dalam pemrograman ap-

1 Beberapa

diantaranya bersifat komersil.

259

260

BAB 23. DATABASE

likasi database adalah melalui tahapan berikut:

1. Login ke database server untuk mendapatkan apa yang disebut sebagai 2. Query

connection ID

2 dengan menggunakan

connection ID

tersebut

3. Menampilkan hasil query (kalau ada)

Proses login setidaknya membutuhkan informasi nama database, username, password, dan hostname (bisa juga nomor IP ). Pada Qt informasi lain yang dibutuhkan adalah nama driver yang akan digunakan. Driver ini merupakan penghubung aplikasi dengan database bersangkutan. Qt memiliki beberapa driver untuk login ke beberapa produk database. Sebelum Anda mencoba contoh program berikutnya, pastikan database PostgreSQL atau MySQL terpasang dengan baik.

3

23.1 Membuat Database
Sebelum membuat tabel, tentu kita perlu membuat databasenya terlebih dahulu, dimana pembahasan menyangkut dua produk database terkemuka yang ada di Linux, yaitu PostgreSQL dan MySQL. User yang digunakan untuk login adalah

superuser

dari masing-masing produk, dimana PostgreSQL dengan user

2 Perintah yang dikirimkan 3 IP: Internet Protocol

ke database server.

23.1. MEMBUAT DATABASE
root-nya.4 ma database yang akan dibuat adalah latihan. postgres-nya,
dan MySQL dengan

261

Sedangkan na-

23.1.1 PostgreSQL
Pertama kali sistem PostgreSQL terpasang, user yang sudah dibuat adalah postgres dengan database template1. Berbekal keduanya, kita akan membuat database yang baru dimana Anda bisa sebagai user Linux apa saja untuk login ke PostgreSQL. Anda tidak perlu membuat program khusus untuk hal tersebut. PostgreSQL memiliki query.

psql

yang dapat digunakan untuk

$ psql -U postgres template1 Welcome to psql, the PostgreSQL interactive terminal. Type: \copyright for distribution terms \h for help with SQL commands \? for help on internal slash commands \g or terminate with semicolon to execute query \q to quit

template1=# CREATE DATABASE latihan; CREATE DATABASE template1=# \q $
4 Linux,
pisah. PostgreSQL, dan MySQL memiliki manajemen user yang ter-

262

BAB 23. DATABASE
$ psql -U postgres latihan Welcome to psql, the PostgreSQL interactive terminal. Type: \copyright for distribution terms \h for help with SQL commands \? for help on internal slash commands \g or terminate with semicolon to execute query \q to quit

Kemudian login ke database latihan:

latihan=#
Sampai di sini Anda siap untuk membuat tabel.

23.1.2 MySQL
MySQL juga memiliki program serupa, yaitu nya pun hampir sama:

5

mysql.

Langkah-

$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 to server version: 3.23.49

Type 'help;' or '\h' for help. Type '\c' to clear the buffer mysql> CREATE DATABASE latihan; Query OK, 1 row affected (0.14 sec)
5 Perhatikan,
option

-u

menggunakan huruf kecil.

23.2. FORM LOGIN
Gambar 23.1: Form Login

263

mysql> \q Bye $
Kemudian lanjutkan dengan login ke database latihan:

$ mysql -u root latihan Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 to server version: 3.23.49 Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>
Kini siap untuk membuat tabel.

23.2 Form Login
Program database biasanya digunakan oleh lebih dari satu orang pengguna (

multiuser ).

Oleh karena itu kita akan membuat se-

buah form untuk proses login dimana pemakai hanya ditanyai username dan password saja. Sedangkan informasi lainnya tertanam dalam program.

264

BAB 23. DATABASE
login.py
berisi Form Login yang dapat dipanggil dari pro-

gram utama untuk proses login. Fitur yang ada dalam form ini adalah: 1. Pengguna cukup mengisikan username dan password, karena data mengenai driver dan hostname sudah dideniskan (hardcode). 2. Untuk login cukup klik tombol OK atau tekan Enter. Meski ada pertanyaan password, Anda bisa mengosongkannya apabila memang instalasi server database masih default.

login.py -------01| from qt import * 02| from qtsql import QSqlDatabase 03| 04| """ Driver 05| QPSQL7 : PostgreSQL 06| QMYSQL3 : MySQL 07| QODBC3 : ODBC 08| QOCI8 : Oracle 09| QTDS7 : Sybase / MS SQL Server 10| """ 11| 12| DB_DRIVER = "QPSQL7" 13| DB_USER = "postgres" 14| 15| #DB_DRIVER = "QMYSQL3"

Password ) .2) layout.setAutoAdd(1) layout.setEchoMode( QLineEdit.2.setSpacing(5) labelUsername = QLabel ( wadahInput ) self.setMargin(5) 265 wadahInput = QWidget(self) layout = QGridLayout(wadahInput.setCaption("Login") layout = QVBoxLayout(self) layout.100) self. 2.setAutoAdd(1) layout. parent) self. parent): QDialog.setText( "Username" ) labelPassword.setText( DB_USER ) self.password.username.username = QLineEdit( wadahInput ) labelPassword = QLabel ( wadahInput ) self.setText( "Password" ) self.__init__(self. FORM LOGIN 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| 41| 42| 43| 44| #DB_USER = "root" #DB_DRIVER = "QOCI8" #DB_USER = "scott" DB_NAME = "latihan" DB_HOST = "localhost" class FormLogin(QDialog): def __init__(self.resize(150.password = QLineEdit( wadahInput ) labelUsername.23.

warning( self.db.text() ) self.exec_loop() def ok(self): self. self.connect(tombolBatal.databaseText().batal) self. DATABASE 45| 46| 47| 48| 49| 50| 51| 52| 53| 54| 55| 56| 57| 58| 59| 60| 61| 62| 63| 64| 65| 66| 67| 68| 69| 70| 71| 72| 73| wadahTombol = QWidget(self) layout = QHBoxLayout( wadahTombol ) layout. "Perhatian". SIGNAL("clicked()").setSpacing(5) tombolOk = QPushButton( wadahTombol ) tombolBatal = QPushButton( wadahTombol ) tombolOk.db.setText ( "OK" ) tombolBatal. SIGNAL("clicked()").addDatabase( DB_DRIVER ) self.password. "Coba lagi".db.db. "Batalkan"): .username. self.setPassword( self.accept() else: if QMessageBox.setText( "Batalkan" ) self.setUserName( self.setAutoAdd(1) layout.lastError().connect(tombolOk.open(): self.db = QSqlDatabase.db.setDatabaseName ( DB_NAME ) self.db.ok) self.setAutoDefault(1) tombolOk.266 BAB 23. self.setHostName ( DB_HOST ) self.text() ) if self.

Berikut ini penjelasan fungsinya: .username.username. Perhatikan baris yang berisi pesan keberhasilan proses login.2.clear() 78| self.reject() 75| else: 76| self.clear() 77| self.23.password.reject() 82| 83| 84| if __name__ == "__main__": 85| app = QApplication([]) 86| if FormLogin(None).setFocus() 79| 80| def batal(self): 81| self. Pada blok itulah Anda dapat meletakkan pemanggilan form utama. QSqlDatabase di atas adalah class untuk login ke server database. FORM LOGIN 74| self.db.isOpen(): 87| print "Login berhasil" 88| else: 89| print "Login dibatalkan" 267 Bagi pengguna MySQL hapuslah remark (#) pada baris berikut: #DB_DRIVER = "QMYSQL3" #DB_USER = "root" Form ini dapat digunakan sebagai otorisasi penggunaan program dimana aplikasi tidak perlu dilanjutkan manakala proses login gagal.

Melanjutkan program buku alamat yang lalu dimana nama dan alamat disimpan dalam sebuah le. DATABASE mengembalikan addDatabase() QSqlDatabase juga. Fungsi ini membutuhkan nama driver yang akan digunakan untuk menghubungi server database. Fungsi salahan. login ke server database. setDatabaseName() setUsername() setPassword() open() isOpen() menentukan nama database yang digunakan.268 BAB 23. menentukan user yang digunakan untuk login. menentukan password. kini akan disimpan dalam tabel relasi. mengembalikan logika true bila login berhasil. mengembalikan nilai bertipe lastError() QSqlError yang memuberisi pesan ke- at berbagai informasi mengenai kesalahan login atau query. Perintah CREATE TABLE digunakan untuk membuat struktur serta aturan main suatu tabel. setHostName() menentukan nama atau nomor IP komputer di- mana server database berada. . databaseText()-nya 23.3 Membuat Tabel Database latihan yang sudah dibuat akan kita isi dengan tabel.

7 Structured Query Language 8 Disebut juga sebagai perintah query .23. berfungsi untuk menampilkan. Dengan kata lain tidak boleh ada nama yang sama dalam tabel relasi. sedangkan VARCHAR dan TEXT adalah tipe datanya. memasukkan data. Ketiadaan boleh tidak. PRIMARY KEY menunjukkan eld tersebut merupakan identitas record. dan DELETE. TEXT juga string namun dengan jumlah karakter yang tidak dibatasi. 6 Kehampaan dalam eld adalah NULL.8 Keempatnya merupakan perintah SQL standar yang berlaku di berbagai produk database berbasis SQL. NOT NULL menunjukkan alamat boleh diisi 23. latihan=# nama dan alamat disebut sebagai eld. UPDATE. QUERY 269 latihan=# CREATE TABLE relasi( latihan(# nama VARCHAR(30) NOT NULL PRIMARY KEY. latihan(# alamat TEXT).4 Query Berbicara mengenai database . INSERT. NOT NULL menunjukkan suatu 6 eld tidak boleh hampa.tidak terlepas dari 7 SELECT. Perlu diketahui juga bahwa string hampa ("") yang selama ini kita kenal sebagai kehampaan bagi string bukan kehampaan bagi eld. serta mengubah maupun menghapusnya.terutama yang berbasis SQL .4. VARCHAR(30) adalah tipe data string dengan jumlah karakter maksimum 30 banyaknya.

270 BAB 23. Nama ditampilkan dalam sebuah combobox yang dapat di-edit..py ---------001| from qt import * 002| from qtsql import QSqlQuery 003| from string import replace 004| from login import FormLogin . relasi3. 2. DATABASE Kini akan kita buat form yang memiliki keempat fungsi terse- but sesuai dengan struktur tabel di atas. Alamat yang tampil akan disesuaikan dengan nama yang tampak pada combobox. Agar bisa membedakannya. di dalam daftar combobox ditambahkan satu data buatan ( virtual ) yang berisi string <baru> dan diletakkan paling atas pada daftar. Sedangkan alamat tetap ditampilkan dalam textedit. Apabila data merupakan hasil perubahan maka ia menggunakan UPDATE. Sehingga cukup klik pada string tersebut untuk menambah data. Tombol simpan dihadapkan pada dua kemungkinan dalam menyimpan data: 1. Ada dua tombol untuk menyimpan dan menghapus. 2. Apabila data baru maka ia menggunakan INSERT. Fitur lainnya adalah: 1. 3.

databaseText().setCaption("Relasi") 019| layout = QGridLayout( self.setText("Alamat") 032| self.setMargin(5) 023| 024| labelNama = QLabel (self) 025| self. QUERY 271 005| 006| def strSql(s): 007| return replace("%s" % s.setAutoAdd(1) 021| layout. "") 008| 009| def salahQuery( parent.lastQuery() ) 012| QMessageBox. query ): 010| s = "%s\n%s" % ( query.warning(parent. 011| query.nama = QComboBox (self) 026| labelAlamat = QLabel (self) 027| self. "'".__init__(self) 018| self. s ) 013| 014| 015| class FormRelasi(QWidget): 016| def __init__(self): 017| QWidget.4.insertItem("<baru>") .setText ("Nama") 031| labelAlamat.alamat = QTextEdit (self) 028| tombolSimpan = QPushButton(self) 029| tombolHapus = QPushButton(self) 030| labelNama.setSpacing(5) 022| layout. "Perhatian".nama.23. 3.lastError().2) 020| layout.setEditable(1) 033| self.nama.

next(): self. SIGNAL("activated(int)").next() self.nama.connect( tombolHapus.value(0). self. SIGNAL("clicked()").alamat.nama. DATABASE 034| 035| 036| 037| 038| 039| 040| 041| 042| 043| 044| 045| 046| 047| 048| 049| 050| 051| 052| 053| 054| 055| 056| 057| 058| 059| 060| 061| 062| self.clearEdit() tombolSimpan.execQuery( sql ) self.setFocus() self.nama. self.clearEdit() self.query.clear() else: nama = strSql( self.setText( .query = QSqlQuery( "SELECT nama FROM relasi" ) while self.nama.toString() ) self.show() self.query.nama.setText("&Simpan") tombolHapus. SIGNAL("clicked()").connect( self.272 BAB 23.query.query.setText ("&Hapus") self. self.connect( tombolSimpan.hapus ) def pilihNama(self.alamat.pilihNama ) self. index): if index == 0: self.text(index) ) sql = "SELECT alamat FROM relasi WHERE \ nama='%s'" % nama self.nama.simpan ) self.insertItem( self.

index ) else: salahQuery(self.nama. '%s' )" % ( nama.currentItem() insert = index == 0 nama = strSql( self.value(0).23.currentText() ) alamat = strSql( self.nama.query.nama.nama.currentText().query) def hapus(self): . alamat ) else: _nama = strSql( self. alamat='%s' WHERE nama='%s'" % ( nama.query. QUERY 063| 064| 065| 066| 067| 068| 069| 070| 071| 072| 073| 074| 075| 076| 077| 078| 079| 080| 081| 082| 083| 084| 085| 086| 087| 088| 089| 090| 091| 273 self. index ) self.currentText().4.changeItem( self.execQuery( sql ): if insert: index = index + 1 self.nama.text(index) ) sql = "UPDATE relasi SET " + \ "nama='%s'.nama.nama. alamat ) " + \ "VALUES( '%s'. _nama ) if self. alamat.text() ) if insert: sql = "INSERT INTO relasi ( nama. self.nama.setCurrentItem( index ) else: self.insertItem( self.alamat.toString() ) def simpan(self): index = self.

DATABASE 092| if self.1 100| self.nama.274 BAB 23.nama.setMainWidget(fm) 109| app.isOpen(): 107| fm = FormRelasi() 108| app.exec_loop() QSqlQuery query.query = QSqlQuery() self.pilihNama( index ) 102| else: 103| salahQuery(self.nama.db.count(): 099| index = index .text(index) ) 095| sql = "DELETE FROM relasi WHERE nama='%s'" % nama 096| if self.query.nama. class ini dapat langsung menerima perintah tersebut atau tidak.query.nama.currentItem() <= 0: return 093| index = self.query = QSqlQuery( "SELECT nama FROM relasi" ) dapat ditulis self.execQuery( "SELECT nama FROM relasi" ) .execQuery( sql ): 097| self. dimana baris merupakan objek yang digunakan untuk perintah self.removeItem( index ) 098| if index + 1 > self.setCurrentItem( index ) 101| self. Pada saat penciptaannya (__init__()).query) 104| 105| app = QApplication([]) 106| if FormLogin(None).currentItem() 094| nama = strSql( self.nama. self.

Sedangkan masukan kedua ( optional 9 ) untuk menentukan 9 Optional: boleh disertakan boleh tidak. selain dipakai untuk me- nampilkan daftar nama juga untuk menambahkan data baru dan juga mengubah data yang lama. la query berhasil ia mengembalikan logika true. QVariant berisi nilai eldnya. Lihat pembahasan sebelumnya mengenai primary key. value() Lebih lanjut mengenai fungsi ini lihat penjelasan lah fungsi Fungsi ini membutuhkan masukan beruLebih lanjut pa nomor index eld dimana 0 berarti eld pertama.4. QUERY execQuery() digunakan untuk menjalankan perintah query. Masukan pertamanya berupa string yang akan ditambahkan dalam daftar. record dari hasil query digunakanlah mengenai patkan current record di bawah. mengembalikan nilai mengenai ter kutip Fungsi QVariant lihat halaman 190. . Sedangkan untuk mendanilai dari setiap eld pada record tersebut digunakanvalue().23. Berikut ini daftar fungsi yang belum dibahas sebelumnya: insertItem() menambah data. pada query melibatkan eld ini merupakan primary key tabel nama dikarenakan eld relasi. Menggantinya dengan kutip tunggal dua kali berarti memberitahu server database bahwa itu kutip tunggal. Untuk mendapatkan fungsi next(). QComboBox memiliki fungsi ganda. melalui fungsi 275 Bi- Pada contoh di atas bila query gagal akan ditampilkan pesan kesalahannya WHERE salahQuery(). strSql() dibuat untuk mengantisipasi adanya karaktunggal ( ' ) pada nilai eld.

record ke n. menentukan nomor index yang aktif (ter- setCurrentItem() removeItem() pilih). rarti at() . ke record pertama. ke record terakhir. DATABASE posisi string tersebut disisipkan. Record pertama be= 0.4. clearEdit() menghapus isi editor. menghapus daftar pada nomor index tertentu.276 BAB 23. Fungsi ini mempengaruhi currentItem(). artinya hanya ada satu record yang aktif dalam satu saat. ke record sebelumnya. penunjuk record. 23.1 Current Record QSqlQuery bekerja dengan sistem current record. Bila tidak disebutkan maka string akan diletakkan di paling bawah. Nomor index current record. Sehingga untuk mendapatkan nilai eld di record tertentu. Anda perlu memindahkan QSqlQuery memiliki beberapa fungsi navigasi untuk memindahkan penunjuk record: next() prev() first() last() seek(n ) at() ke record berikutnya.

value(0). dan 277 last() mengembalikan logika true apabila berhasil ke record yang dimaksud.2 Variant Seperti dibahas sebelumnya bahwa balikan QSqlQuery. prev(). lalu cobalah query1.value() mengemQVariant. q.prev(): 12| print q. first(). Variant atau QVariant merupakan tipe data apa saja.toString().next(): 09| print q. QVariant memiliki banyak fungsi konversi ke berbagai bentuk tipe data seperti: toString()QString .23.toString() 10| print 11| while q.value(1).db.4.isOpen(): 07| q = QSqlQuery("SELECT nama.toString() 23.toString().value(1). QUERY next().4. alamat FROM relasi") 08| while q.py --------01| from qt import * 02| from qtsql import QSqlQuery 03| from login import FormLogin 04| 05| app = QApplication([]) 06| if FormLogin(None).value(0). isilah tabel relasi dengan beberapa record. Untuk lebih memahami bagaimana fungsi navigasi pada menjalankan contoh berikut: QSqlQuery bekerja. q.

5 Cara Lain Menangani Tabel Dengan QSqlQuery manipulasi data tabel sudah dapat dilakukan.278 BAB 23. yaitu QSqlCursor.10 merupakan turunan dari 10 Sebagaimana C++.Date QDate QVariant.Double QVariant.Time QTime QVariant. DATABASE toDateTime()QDateTime toDouble()oat toInt()integer Untuk mengetahui tipe data suatu variant dapat menggunakan fungsi QVariant. Class ini QSqlRecord.Int oat integer QVariant. Python membolehkan suatu class merupakan tu- runan beberapa class.String QString QVariant.DateTime QDateTime 23. .type() yang akan mengembalikan konstanBeberapa di- ta integer berupa nomor tipe yang dimaksud. antaranya adalah: QVariant. juga dan Qt memiliki class lainnya sebagai alternatif yang lebih mu- QSqlQuery dah.

value("nama").value("alamat").toString().databaseText() select() digunakan untuk menjalankan query SELECT.isOpen(): 07| c = QSqlCursor( "relasi" ) 08| if c.select(): 09| while c. 11 Baris c. Bila ingin ditambahkan suatu kondisi. CARA LAIN MENANGANI TABEL 279 cursor1.select() sama artinya dengan query SELECT * FROM relasi.toString() 12| else: 13| print c. bisa langsung disertakan pada select() akses (GRANT) bagi user yang sedang login terhadap tabel 11 Contoh kegagalan query pada contoh di atas adalah ketiadaan hak relasi.db.23. \ 11| c.py ---------01| from qt import * 02| from qtsql import QSqlCursor 03| from login import FormLogin 04| 05| app = QApplication([]) 06| if FormLogin(None). .next(): 10| print c.5.lastError(). Ia mengembalikan logika true apabila query berhasil.

23.dengan alasan tersebut .setCaption("Tabel relasi") . Cobalah ini: menampilkan isi program berikut datatable1. Namun dalam beberapa hal dengan QSqlQuery proses query jauh lebih cepat.py ------------01| from qt import * 02| from qtsql import QSqlCursor. Jadi yang paling penting keduanya akan kita gunakan pada kasus yang sesuai dengan tur masing-masing.280 BAB 23. QDataTable 03| from login import FormLogin 04| 05| class FormRelasi(QWidget): 06| def __init__(self): 07| QWidget.diharapkan lebih memudahkan programmer karena tidak perlu menuliskan query.5. DATABASE c.select("nama='Budi'") value() pada QSqlCursor selain dapat beru- Nilai masukan bagi pa nomor urut eld juga dapat berupa nama eldnya.1 Browsing QDataTable merupakan QTable yang dapat record QSqlCursor secara otomatis.__init__(self) 08| self. Praktis QSqlCursor menawarkan gaya Qt dalam memprogram database dan .

yang dapat ditampilkan deMenu ini berisi In- sert.setMainWidget(fm) 21| app. Sebagai gantinya untuk menampilkan kolom tertentu gunakan addColumn().5. CARA LAIN MENANGANI TABEL 281 09| layout = QHBoxLayout(self) 10| layout. "Nama Relasi") QDataTable memiliki menu ngan cara klik-kanan 12 pada popup QDataTable. self.setSqlCursor(self.cursor) self. . 12 Klik-kanan: klik tombol mouse paling kanan.table. Bila Anda hanya ingin menampilkan eld tertentu saja maka jangan sertakan angka 1 tersebut.cursor = QSqlCursor( "relasi" ) 12| self.cursor. Angka 1 (true) pada masukan kedu- anya (optional) berarti menampilkan kolom sebanyak jumlah eld pada tabel bersangkutan.show() 16| 17| app = QApplication([]) 18| if FormLogin(None). Update.table.table.refresh() 15| self.setAutoAdd(1) 11| self.addColumn("nama". 1) 14| self.23.table. dan Delete yang mewakili perintah SQL untuk memanipulasi record.setSqlCursor(self.table = QDataTable(self) 13| self.db.isOpen(): 19| fm = FormRelasi() 20| app.exec_loop() fungsi QSqlCursor dipakai oleh QDataTable sebagai sumber data melalui setSqlCursor().

gaji. waktu_input DATETIME NOT NULL. nama VARCHAR(30) NOT NULL.waktu_input) VALUES (2. buatlah struktur tabel pegawai berikut ini.'1973-12-20'. gaji FLOAT NOT NULL.tgl_lahir. jadual_masuk TIME.'07:30'.jadual_masuk.jadual_masuk. bisa melalui program psql atau mysql: CREATE TABLE pegawai( id INTEGER NOT NULL.gaji.'1974-01-03'.282 BAB 23. misalnya bilangan pecahan dan yang berkaitan dengan waktu.tgl_lahir. tgl_lahir DATE NOT NULL.nama. INSERT INTO pegawai (id.5.2500000.2 Bentuk Tampilan Tampilan nilai eld pada beberapa tipe data yang sering digunakan.waktu_input) VALUES (1. DATABASE QDataTable masih perlu diuji dengan Oleh karena itu. 23. lalu isi dengan query ini: INSERT INTO pegawai (id.1500000.'Prakoso'.NULL.'Anom'.nama. . PRIMARY KEY (id) ). '2003-01-17 12:59:48').

23.5. dan hanya ada dua angka di belakang koma. Field tidak perlu ditampilkan apa-apa.'Budi Respati'. 3. memiliki pemisah ribuan. datatable1.gaji.tgl_lahir.3.nama. '2003-01-17 13:14:56').'1973-12-20'.ditampilkan rata kanan. Format waktu sesuai gaya Indonesia. ada beberapa hal yang perlu "dikoreksi QDataTable NULL 1. Format bilangan pecahan (oat) perlu ditampilkan secara utuh.jadual_masuk. ini: Dari hasil tersebut.'07:30'. kemudian ubahlah dengan "dari pegawai.py dimana tabel relasi diganti Lalu lihat hasilnya seperti pada gambar 23. 20xx.3: QDataTable 283 '2003-01-17 13:09:34'). CARA LAIN MENANGANI TABEL Gambar 23. 2.baik integer maupun oat . INSERT INTO pegawai (id.1750000. Bilangan . 4.waktu_input) VALUES (3. Tahun juga perlu ditampilkan secara utuh untuk membedakan 19xx dengan . rata kanan.

LC_ALL.LTR 18| else: 19| align = QPainter. QVariant. Jam) 11| 12| def __init__(self.isNull(): 21| teks = "" 22| elif field.toDouble(). cr.type() == QVariant.setlocale(locale. 24| field. "") 06| 07| class CursorTable(QDataTable): 08| Tanggal = "dd-MM-yyyy" 09| Jam = "hh:mm:ss" 10| Waktu = "%s %s" % (Tanggal. field.__init__(self.Double: 23| teks = locale. Kita namakan saja cursortable.284 BAB 23. selected): 16| if field.2f". 1 ) . Oleh karena itu perlu dibuat class baru turunan tuk mewujudkan tur tersebut.value().Double]: 17| align = QPainter.format( "%.RTL 20| if field. DATABASE QDataTable unCursorTable. painter.py -------------01| from qt import * 02| from qtsql import QDataTable 03| import locale 04| 05| locale. parent) 14| 15| def paintField(self.Int.type() in [QVariant. parent): 13| QDataTable.

type() == QVariant. cr.23.height()-4.refresh() 49| fm. cr.value().drawText(2.toTime().toDateTime().setSqlCursor( cursor.toString() 35| painter.type() == QVariant.db. 36| align.value().type() == QVariant.DateTime: 29| teks = field.exec_loop() .5. 1 ) 48| fm.isOpen(): 45| cursor = QSqlCursor( "pegawai" ) 46| fm = CursorTable(None) 47| fm.value().Tanggal) 28| elif field. teks ) 37| 38| 39| if __name__ == "__main__": 40| from login import FormLogin 41| from qtsql import QSqlCursor 42| 43| app = QApplication([]) 44| if FormLogin(None).Date: 26| teks = field.show() 50| app.Time: 32| teks = field.toString( 27| self.2.toString( 30| self.toString(self.width()-4.Waktu) 31| elif field.value(). CARA LAIN MENANGANI TABEL 285 25| elif field.setMainWidget(fm) 51| app.toDate().Jam) 33| else: 34| teks = field.

db. Record diubah dan ditampilkan kembali hasil perubahannya. UPDATE.4: CursorTable Jalankan program di atas.4.isOpen(): 07| c = QSqlCursor( "relasi" ) 08| c. Contoh berikut ini menampilkan fungsi ketiganya dengan skenario sebagi berikut: 1. cursor2.3 Pengganti Perintah SQL QSqlCursor dibuat sebagai jalan lain untuk melakukan INSERT. 2.select() . Record ditambahkan. dan contoh tampilannya dapat dilihat pada gambar 23.py ---------01| from qt import * 02| from qtsql import QSqlCursor 03| from login import FormLogin 04| 05| app = QApplication([]) 06| if FormLogin(None). dan ditampilkan. DATABASE Gambar 23. 3.286 BAB 23.5. 23. maupun DELETE. Tabel relasi dikosongkan.

primeInsert().toString().value("nama").primeDelete() c. \ c.toString() QSqlCursor bekerja dengan sistem buer 13 untuk memanipulasi data.value("alamat"). Ketiga fungsi ini mengembalikan QSqlRecord.toString().update() c. maupun primeDelete() digunakan untuk mempersiapkan buer ini.setValue("alamat".next(): c. primeUpdate().select() while c.next(): print c. \ c. QVariant("Bogor") ) c.next(): print c.23.select() 287 b = c.primeInsert() b. QVariant("Jakarta") ) c. Jalan lain untuk mendapatkan 13 Buer: penyimpanan sementara.setValue("nama".value("nama").setValue("alamat".toString() b = c. QVariant("Udin") ) b. .primeUpdate() b.delRecords() c. CARA LAIN MENANGANI TABEL 09| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30| 31| while c.5.insert() c.select() while c.value("alamat").

primeUpdate() b.setValue("alamat". 23. Sama halnya dengan perintah update() dan delRecords() pada QSqlCursor. UPDATE dan DELETE Tan- Kondisi yang dimaksud untuk mencari identitas suatu record UPDATE dan DELETE tidak dapat menentukan record yang dimaksud. QVariant("Bogor") ) c. DATABASE editBuffer() pada QSqlCursor.primeUpdate() c.editBuffer().update() bisa ditulis c.4 NULL NULL merupakan kehampaan bagi eld dalam SQL. yang tercermin dalam primary key pada struktur tabel. Fungsi field() dapat digunakan untuk mendapatkan objek eld (QSqlField) . panya. Jika tabelnya tidak memiliki primary key maka kedua perintah tersebut tidak melakukan apa-apa dan mengembalikan FALSE. buer ini adalah melalui fungsi Jadi baris b = c. QVariant("Bogor") ) c.setValue("alamat".288 BAB 23.5.update() Primary Key Telah dibahas pada contoh sebelumnya bahwa membutuhkan kondisi (WHERE) untuk mengubah suatu record.

yaitu QSqlRecord.clear() 12| c.value("alamat").5.toString().select() 14| while c.update() 13| c.next(): 15| print c.value("nama").db.toString() 17| else: 18| print "Udin belum terdaftar" Objek eld ini sebenarnya milik leluhur QSqlCursor.primeUpdate() 11| b. Dengan objek eld ini kita dapat menghapus Contoh berikut ini akan menghapus eld Udin. .select("nama='Udin'") 09| if c. \ 16| c.next(): 10| b = c.py ---------01| from qt import * 02| from qtsql import QSqlCursor 03| from login import FormLogin 04| 05| app = QApplication([]) 06| if FormLogin(None). CARA LAIN MENANGANI TABEL pada nilai eld (men-NULL-kan) dengan fungsi 289 QSqlCursor. alamat pada nama cursor3.isOpen(): 07| c = QSqlCursor( "relasi" ) 08| c.field("alamat"). clear().23.

Current record memiliki tiga status: Browse (tersimpan). Update (sedang diubah untuk di-UPDATE).py. Misalkan sekarang tanggal 17-2-2003. 5. Sama seperti QDataTable.234. Dengan fungsi angka() 15 maka masukan bisa berupa rumus matematika. 15 Fungsi angka() berada pada le fungsi. 6. 4. Waktu bisa ditulis now yang berarti saat ini.menambah waktu proses input karena meli- Grid 14 dengan tambahan tur sebagai berikut: 1. Penggunaan menu popup pada batkan dua alat yaitu keyboard dan mouse.56 (desimal boleh dengan koma atau titik). dan Insert (sedang 3.290 BAB 23. DATABASE 23. Bentuk tampilan untuk eld angka dan waktu disesuaikan dengan ciri Indonesia. misalkan angka yang tampil 1.56 atau 1234. kita akan membuat class baru keturunan QDataTable .5.56 namun pada saat memasukkan data cukup ditulis 1234. sumberdatanya QSqlCursor. Penyesuaian bentuk tampilan.5 Pengisian Data yang Lebih Nyaman Kebanyakan orang terbiasa dengan aplikasi spreadsheet untuk memasukkan data.sedikit banyak . 2. Masukan tanggal yang tidak lengkap akan dilengkapi dengan waktu saat ini. 14 Lihat halaman 157 mengenai class ini. fungsi ini. Lihat halaman 161 tentang . Untuk memperbaikinya. diubah untuk di-INSERT).

Misalkan hanya dimasukkan angka 10 maka menjadi 10:00:00. Masukan jam juga bisa ditulis depannya saja.5: DBGrid 291 bila hanya angka 10 yang dimasukkan maka menjadi 10- 2-2003. dan waktu(). Bila terjadi kesalahan input. QDateTime. QTime.5. Class baru ini dinamakan tabel dari database. CARA LAIN MENANGANI TABEL Gambar 23. jam(). 7. Bila masukannya 31-1 maka menjadi 31-1-2003. 9. serta Ketiganya menerima masukan string dan mengubahnya menjadi QDate. fungsi. nilai dikembalikan seperti semula.py --------001| from qt import * 002| import string 003| import locale . Konsep produk tersebut. merupakan nama objek pada produk Borland Delphi yang berfungsi untuk menampilkan DBGrid di sini memang berasal dari dengan tiga fungsi baru yaitu: fungsi. Modul DBGrid. Untuk tipe DATETIME tanggal dan jam dipisahkan spasi. masing-masing dengan aturan penulisan seperti di atas. 8.23.py yang pernah dibuat sebelumnya akan dilengkapi tanggal().

DATABASE 004| 005| 006| 007| 008| 009| 010| 011| 012| 013| 014| 015| 016| 017| 018| 019| 020| 021| 022| 023| 024| 025| 026| 027| 028| 029| 030| 031| 032| locale.format( "%d". """ def ribu(n): if type(n) == type(0): return locale.") try: return int(a) except ValueError: try: return float(a) except ValueError: if a and a[0] == "=": . 1 ) else: return "" """ Mengubah string menjadi angka. 1 ) elif type(n) == type(0.2f".strip("%s" % s) a = string. Membolehkan rumus matematika.".format( "%.0): return locale. n. """ def angka(s): a = string.292 BAB 23.LC_ALL. n.setlocale(locale.".". "") """ Mengubah angka menjadi string dengan format ribuan. Membolehkan pemisah pecahan dengan koma.replace(a.

p) 053| 054| try: d = int(t[0]) 055| except ValueError: return 056| 057| # Untuk bulan dan tahun default 058| now = QDate.5.currentDate() 049| 050| if string.upper(w) == "NOW": 048| return QDate.find(w.currentDate() 059| 060| if t[1:]: 061| try: m = int(t[1]) . 044| """ 045| def tanggal(s): 046| w = string.23. Bila hanya dd maka MM dan yyyy diisi bulan 042| dan tahun sekarang. "-") > -1: p = "-" 051| else: p = "/" 052| t = string. Bila hanya dd-MM maka yyyy diisi 043| tahun ini.splitfields(w. Bila 'NOW' berarti tanggal sekarang.strip("%s" % s) 047| if string. CARA LAIN MENANGANI TABEL 293 033| try: 034| exec("a"+a) 035| return a 036| except: 037| return 038| 039| 040| """ Mengubah string tanggal format dd-MM-yyyy menjadi 041| QDate.

m = now. DATABASE 062| except ValueError: return 063| if t[2:]: 064| try: y = int(t[2]) 065| except ValueError: return 066| else: 067| y = now. d ) 072| if tgl.zzz menjadi 076| QTime.isNull(): return tgl 073| 074| 075| """ Mengubah string jam bentuk hh:mm:ss.":") 084| 085| try: h = int(t[0]) 086| except ValueError: return 087| 088| if t[1:]: 089| try: m = int(t[1]) 090| except ValueError: return . 077| Begitu seterusnya.splitfields(w.year() 068| else: 069| y.strip("%s" % s) 081| if string. now.isValid() and not tgl.month() 070| 071| tgl = QDate( y.currentTime() 083| t = string.upper(w) == "NOW": 082| return QTime.year(). 078| """ 079| def jam(s): 080| w = string. m.294 BAB 23. Bila hanya hh maka lainnya dianggap nol.

isValid() and not j. 0 105| else: 106| m. 0 107| j = QTime(h.23.strip("%s" % s) 116| if string.splitfields("%s" % w) .5.zzz 112| menjadi QDateTime 113| """ 114| def waktu(s): 115| w = string. ms = 0.".m." + x[1] 099| try: ms = float(y) * 1000 100| except ValueError: return 101| else: 102| ms = 0 103| else: 104| s. CARA LAIN MENANGANI TABEL 295 091| if t[2:]: 092| x = t[2] 093| x = string.") 095| try: s = int(x[0]) 096| except ValueError: return 097| if x[1:]: 098| y = "0.") 094| x = string. s. ms = 0. 0.".replace(x.".isNull(): return j 109| 110| 111| """ Mengubah string waktu bentuk dd-MM-yyyy hh:mm:ss.currentDateTime() 118| 119| w = string.splitfields(x.upper(w) == "NOW": 117| return QDateTime.".s.ms) 108| if j.

296 BAB 23.0.py ini.py --------001| from qt import * 002| from qttable import QTable 003| from qtsql import QSqlIndex 004| import string 005| from grid import Grid 006| from fungsi import * 007| from linecase import LineCase 008| 009| class DBGrid(Grid): 010| Tgl = "dd-MM-yyyy" 011| Jam = "hh:mm:ss" 012| Wkt = "%s %s" % (Tgl.py berikut dbgrid. t ) di atas akan digunakan dalam fungsi.0) return QDateTime( d.0. dbgrid. Jam) 013| 014| # status current record 015| Browse = 0 016| Insert = 1 . DATABASE 120| 121| 122| 123| 124| 125| 126| if w: d = tanggal(w[0]) else: return if w[1:]: t = jam(w[1]) else: t = QTime(0.

afterInsert = None # event setelah tambah() self.__init__(self.setStyle( QBrush.penBox = QPen() self.beforePost = None # event sebelum UPDATE/INSERT self.brushUpdate = QBrush() self.brushBrowse.SolidPattern ) self.doubleValidator = QDoubleValidator(self) self._maxLength = {} # fieldname:length self.brushInsert.brushUpdate.brushBrowse = QBrush() self.brushUpdate.23._cursor = None self._row = -1 # sebelum currentRow() self.status = self.penBox.setColor( QColor("cyan") ) self.brushInsert.penText.afterPost = None # event sesudah UPDATE/INSERT .penText = QPen() self.5.editRow = -1 # baris yang sedang diedit self.SolidPattern ) self.setColor( QColor("black") ) self.Browse self.brushInsert = QBrush() self._col = -1 # sebelum currentColumn() self. parent) self.setColor( QColor("lightGray") ) self.setStyle( QBrush.setStyle( QBrush.SolidPattern ) self.setColor( QColor("yellow") ) self.intValidator = QIntValidator(self) self. CARA LAIN MENANGANI TABEL 017| 018| 019| 020| 021| 022| 023| 024| 025| 026| 027| 028| 029| 030| 031| 032| 033| 034| 035| 036| 037| 038| 039| 040| 041| 042| 043| 044| 045| Update = 2 297 def __init__(self. parent): Grid._case = {} # fieldname:Normal|Upper|Lower self.setColor( QColor("green") ) self.brushBrowse.

col.name()) if self. SIGNAL("currentChanged(int._maxLength. case) if field. row. replace): if self.beginEdit(self._case[fieldname] else: case = LineCase.298 BAB 23. col.Normal e = LineCase(self.ubah(): return QTable.intValidator ) elif field.isNull(): s = "" elif field.type() == QVariant.has_key(fieldname): e. i): pass # hemat memory def beginEdit(self.editBuffer().setMaxLength(self._case.saatPindah) def resizeData(self.field(col) fieldname = str(field.Int: e.has_key(fieldname): case = self.type() == QVariant.doubleValidator ) if initFromCell: if field.String: if self.int)"). row.type() == QVariant.Double: e. col. DATABASE 046| 047| 048| 049| 050| 051| 052| 053| 054| 055| 056| 057| 058| 059| 060| 061| 062| 063| 064| 065| 066| 067| 068| 069| 070| 071| 072| 073| 074| self. initFromCell): field = self.setValidator( self.type() == QVariant. replace) def createEditor(self.connect(self. row.setValidator( self. self._cursor._maxLength[fieldname]) elif field.Date: .

type() == QVariant.value(). row.toTime()._cursor. col): if self.toString(self.value().setRight( self.ubah().type() == QVariant.insertRows(self. row) self._cursor.0) r.Double: s = str(field.toDateTime().Time: s = field. col) def insertRows(self.isiDariEditor() def clearCell(self.toInt()) else: s = field.toDouble()) elif field.DateTime: s = field.simpan() or self.Tgl) elif field.field(col).type() == QVariant.type() == QVariant.seek(row): self.value(). col): self.clear() self. count=1): if not self.value().updateCell(row.value().Int: s = str(field.toString() e.setText( s ) return e def setCellContentFromEditor(self. row.width() ) .value(). CARA LAIN MENANGANI TABEL 075| 076| 077| 078| 079| 080| 081| 082| 083| 084| 085| 086| 087| 088| 089| 090| 091| 092| 093| 094| 095| 096| 097| 098| 099| 100| 101| 102| 103| 299 s = field.5.tambah() r = self.toDate().toString(self.cellGeometry(row-1.23.Wkt) elif field.size() < 1: return Grid.toString(self. row.Jam) elif field.

_refresh() self.naik() elif e. DATABASE 104| 105| 106| 107| 108| 109| 110| 111| 112| 113| 114| 115| 116| 117| 118| 119| 120| 121| 122| 123| 124| 125| 126| 127| 128| 129| 130| 131| 132| r.setStatus( self.removeRow( self.simpan() elif e.editBuffer()._cursor.key() == Qt.repaintContents(r) else: self. row.setRight( self. row ) def keyPressEvent(self.removeRow( self.batal() elif e.width() ) self._cursor: return if row == self.primeDelete() if self.salah() else: Grid.key() == Qt._cursor.repaintContents(r) def removeRow(self. row): if not self. col.setBottom( self.height() ) self.keyPressEvent(self. 0 ) r. row ) r = self.perbaharui() else: Grid.300 BAB 23.Insert: ._cursor.Key_F4: self. selected): if not self.editRow: field = self.Key_F5: self.key() == Qt.key() == Qt.delRecords(): self.Key_Escape: self. e): if e.status == self. e) def paintCell(self.adaPrimaryKey(): return if self.Browse ) Grid. painter.Key_Up: self. cr.cellGeometry( self.field(col) elif self.currentRow()._cursor.seek( row ): self.

editRow: if self.width().brushUpdate ) elif row == self.RTL if row == self.width().Insert: painter.Double]: align = QPainter.field(col) else: field = None elif self._cursor.LTR else: align = QPainter. cr.brushBrowse ) else: . self._cursor.0. cr.brushInsert ) else: painter. cr. cr.fillRect( 0.height().editRow: r = row .seek(row): field = self.field(col) else: field = None s = self. self.Int. cr._cursor.fillRect( 0. self._cursor.height().size() > 0: painter.5.0. QVariant. CARA LAIN MENANGANI TABEL 133| 134| 135| 136| 137| 138| 139| 140| 141| 142| 143| 144| 145| 146| 147| 148| 149| 150| 151| 152| 153| 154| 155| 156| 157| 158| 159| 160| 161| 301 if row > self.23.seek(r): field = self.fillRect( 0.currentRow() and \ self.strField( field ) if field and field.1 else: r = row if self.height().status == self. cr.type() in [QVariant.0._cursor.width().

toDouble())) elif field.setPen( self.penBox ) painter. cr.isEmpty() and \ .toString()) return s def setSqlCursor(self.2.value().toString(self.type() == QVariant.DateTime: s = field. cursor): if cursor: if cursor.toString(self.toDate(). cr. align.setPen( self.height()-1.type() == QVariant.height()-1.Jam) elif field.value().width()-4. cr.toString(self.Date: s = field. field): if not field or field.302 BAB 23.toTime().width().penText ) painter.width()-1. cr.Int: s = str(ribu( field.value().height() ) def strField(self. 0 ) painter.sort().eraseRect( 0.height()-1 ) painter.type() == QVariant.type() == QVariant. cr.width(). DATABASE 162| 163| 164| 165| 166| 167| 168| 169| 170| 171| 172| 173| 174| 175| 176| 177| 178| 179| 180| 181| 182| 183| 184| 185| 186| 187| 188| 189| 190| painter. s) painter.toDateTime().isNull(): s = "" elif field.Double: s = str(ribu( field. cr.type() == QVariant.drawText(2.value(). cr.width()-1.0.height()-4. cr.Wkt) elif field. cr.toInt())) else: s = str(field.Time: s = field.drawLine( 0.value().value().Tgl) elif field.drawLine( cr.

editRow = -1 219| else: self.status == status: return 217| self. 203| cursor.23.field(i) ) 195| cursor.size() ) 199| self.setLabel(col.count() ): 202| self.setNumRows(0) 207| self._cursor.Browse: self.isEmpty(): 192| index = QSqlIndex() 193| for i in range( cursor. status): 216| if self.primaryIndex()._col = self. CARA LAIN MENANGANI TABEL 303 191| not cursor.5.editRow = self.isEmpty(): 211| self.setNumRows( cursor.count() ): 194| index.field(col).currentRow() 200| self.currentColumn() 201| for col in range( cursor.primaryIndex().append( cursor.setSort( index ) 196| cursor.count() ) 198| self.currentRow() .primaryIndex().horizontalHeader().name() ) 204| else: 205| self.select() 197| self.setNumCols( cursor._cursor = cursor 208| 209| def adaPrimaryKey(self): 210| if self._row = self.") 213| else: return 1 214| 215| def setStatus(self.setNumCols(0) 206| self.pesan("Tabel tanpa Primary Key tidak dapat \ 212| diubah atau dihapus.status = status 218| if status == self.

status == self._cursor) if self.editBuffer() if self.Insert ) if self.beforePost(self.cellGeometry(self.seek( self.width() ) self.editorAktif(): self.currentRow().tambah() if not self. self.primeInsert() for col in range(b.setStatus( self._cursor.repaintContents(r) def tambah(self): b = self. DATABASE 220| 221| 222| 223| 224| 225| 226| 227| 228| 229| 230| 231| 232| 233| 234| 235| 236| 237| 238| 239| 240| 241| 242| 243| 244| 245| 246| 247| 248| r = self.currentRow().Browse: return 1 if self.size() == 0: return self.count()): b.primeUpdate() self._cursor.setStatus( self.currentColumn() ) if self.afterInsert(self._cursor) return b def ubah(self): if self._cursor.adaPrimaryKey(): return if self.0) r.setRight( self.status == self._cursor.clearCellWidget( self.304 BAB 23.isiDariEditor() self.field(col).afterInsert: self.clear() self.Update ) return b def simpan(self): if self.Browse: return self.status != self.Insert: .currentRow() ): b = self._cursor.beforePost: self.

_cursor.afterPost: self._col = row. CARA LAIN MENANGANI TABEL 249| 250| 251| 252| 253| 254| 255| 256| 257| 258| 259| 260| 261| 262| 263| 264| 265| 266| 267| 268| 269| 270| 271| 272| 273| 274| 275| 276| 277| 305 if self.23._cursor) return 1 def saatPindah(self. self.setStatus( self._row: if not self. self._cursor.width() ) self._row. col def naik(self): if self.afterPost(self.cellGeometry( row.update(): self. col): if row != self.Browse ) if self. 0 ) r.simpan(): return r = self.5.setRight( self.currentRow() > 0: self.Update: if self.repaintContents(r) r = self.simpan() and self.currentRow()-1. 0 ) r.salah() return 0 self.currentColumn() ) .repaintContents(r) self.width() ) self.cellGeometry( self. row.salah() return 0 elif self.setRight( self._refresh() else: self.insert(): self.setCurrentCell( self._refresh() else: self._row.status == self.

Insert: Grid.repaintContents(r) self. self.width() ) self. self.cellWidget( self.select() self. DATABASE 278| 279| 280| 281| 282| 283| 284| 285| 286| 287| 288| 289| 290| 291| 292| 293| 294| 295| 296| 297| 298| 299| 300| 301| 302| 303| 304| 305| 306| def batal(self): if self.removeRow( self.repaintContents(r) def salah(self): pesan = "%s\nTekan Escape untuk membatalkan.0) r.currentRow()._row != self.repaintContents() # Berguna pada cursor berkondisi pada select()-nya def perbaharui(self): if self.setCurrentCell( self.setRight( self.width() ) r." % \ self._cursor.select() if self.currentRow().setBottom( self.databaseText() self.cellGeometry( self._col ) self._cursor.height() ) self.status self.setRight( self.306 BAB 23.status != self. 0 ) r._cursor.cellGeometry(self.lastError().setStatus( self.pesan( pesan ) def _refresh(self): self.currentRow() ) r = self.Browse ) if status == self.Browse: status = self._row.currentRow(). .currentRow(): r = self.

23.currentColumn() ): return if self.editBuffer().type() in [QVariant. s) # Tentukan jumlah karakter maksimum untuk field string def setMaxLength(self. fieldname. s): QMessageBox.size() ) def pesan(self.Double]: .type()==QVariant. CARA LAIN MENANGANI TABEL 307| 308| 309| 310| 311| 312| 313| 314| 315| 316| 317| 318| 319| 320| 321| 322| 323| 324| 325| 326| 327| 328| 329| 330| 331| 332| 333| 334| 335| 307 self.currentColumn() ) if field.type()==QVariant.5.currentRow(). QVariant.warning(self._cursor._cursor.cellWidget( self.update( {fieldname:case} ) def editorAktif(self): return self. length): self.update( {fieldname:length} ) # Tentukan uppercase atau tidak untuk field string def setCase(self. "Perhatian"._cursor.text()) field = self.DateTime: s=waktu(s) elif field.field( self.currentColumn() ) def isiDariEditor(self): s = str(self._maxLength._case.Date: s = tanggal(s) elif field.simpan(): self.type()==QVariant.setNumRows( self.Time: s = jam(s) elif field. case): self.select() self.Int. self.editorAktif(). fieldname.

isOpen(): 349| cursor = QSqlCursor( tablename ) 350| cursor. DATABASE 336| s = angka(s) 337| if s: s = str(s) 338| if s: field.exec_loop() Untuk mencobanya jalankan: $ python dbgrid. Bila diizinkan fungsi ini harus mengembalikan widget sebagai editor untuk memasukkan data yang diperoleh lewat createEditor().db.setValue( QVariant(s) ) 339| elif s == "": field.clear() 340| 341| if __name__ == "__main__": 342| from login import FormLogin 343| from qtsql import QSqlCursor 344| import sys 345| 346| tablename = sys.argv[1] 347| app = QApplication([]) 348| if FormLogin(None). Ini saat yang tepat untuk membolehkan atau tidak suatu cell di-edit.py pegawai Fungsi beginEdit() merupakan event yang dipanggil menjelang edit-mode.setSqlCursor( cursor ) 353| fm. .308 BAB 23.select() 351| fm = DBGrid(None) 352| fm.show() 354| app.setMainWidget(fm) 355| app.

Kini hal yang sama akan dibuat untuk eld . nama VARCHAR(20) NOT NULL UNIQUE. UNIQUE identitas record selain eld pada PRIMARY KEY (eld id). DBGrid akan mengurutkan (sorting) data pada tabel berdasarkan primary key yang ada. bukan kode barangnya. Secara umum dikatakan bahwa setiap pergantian baris membuat record tersimpan.5. harga FLOAT NOT NULL). atau langsung tekan panah atas / bawah. Bisa juga menekan F5 yang sekaligus merupakan tombol terhadap tabel barang. CARA LAIN MENANGANI TABEL 309 Untuk menyimpan data yang telah dimasukkan tekan F4. Untuk pencarian nama barang biasanya dibutuhkan nama yang terurut. Catatan Perumusan kode barang diserahkan sepenuhnya pada para pemakai. id sebagai kode CREATE TABLE barang( id INTEGER NOT NULL PRIMARY KEY. fungsi setSqlCursor() sudah memberitahu bagaimana mengunama.23. Source rutkan data berdasarkan eld tertentu. yaitu 23.5.6 Urutkan . pada eld nama berarti eld tersebut juga merupakan Makna lainnya adalah tidak boleh ada nama barang yang sama. query ulang refresh.Sort Sebelumnya kita sudah menyimpan daftar barang dalam sebuah le. Sekarang daftar barang tersebut akan disimpan dalam sebuah tabel barang dengan tambahan eld barang.

field("nama") ) 11| c.melalui sa terlebih dahulu apakah cursor -nya sudah memiliki index.isOpen(): 08| c = QSqlCursor( "barang" ) 09| index = QSqlIndex() 10| index. namun ia .append( c. . setSqlCursor() . DATABASE sqlindex. Pada SQL pengurutan pada contoh di atas berarti SELECT * FROM barang ORDER BY nama.db. QSqlIndex 03| from login import FormLogin 04| from dbgrid import DBGrid 05| 06| app = QApplication([]) 07| if FormLogin(None). Berkaitan dengan sort ini.setSqlCursor(c) 14| fm.310 BAB 23.setMainWidget(fm) 16| app.juga memerikBi- la sudah ia akan menggunakan index yang ada.setSort( index ) 12| fm = DBGrid(None) 13| fm.show() 15| app. Form Pencarian pada halaman 168 akan diubah sedikit karena sumber datanya berasal dari database.exec_loop() Meski DBGrid secara default mengurutkan data berdasarkan primary key.py ----------01| from qt import * 02| from qtsql import QSqlCursor.

Key_Escape: self.position(searchfieldname) 22| self.__init__(self.lanjut() .state() == Qt.append( self. LineCase.escape() 26| elif e._field = cursor._cursor = cursor 20| self.5. CARA LAIN MENANGANI TABEL 311 caritabel. parent.key() == Qt.Key_PageDown: self.field(searchfieldname) 16| index = QSqlIndex() 17| index.setSort(index) 19| self.key() == Qt.setCaption( cursor.23. searchfieldname): 08| QDialog.setSqlCursor( cursor ) 21| self.kolomCari = cursor._field ) 18| cursor.Upper) 12| self.teks = LineCase(self.teksBerubah 23| 24| def keyPressEvent(self.teks.py -----------01| from qt import * 02| from dbgrid import DBGrid 03| from qtsql import QSqlCursor.addWidget(self. parent) 09| self.tabel.ControlButton and \ 27| e.teksBerubah = self.tabel) 15| self.name() ) 10| layout = QVBoxLayout(self) 11| self. e): 25| if e.tabel = DBGrid(self) 13| layout.teks) 14| layout. cursor.addWidget(self. QSqlIndex 04| from linecase import LineCase 05| 06| class FormCari(QDialog): 07| def __init__(self.

tabel.tabel.teks._cursor. Qt. awalan=1.numRows()-1: brs = brs + 1 self. "Perhatian".teks.text()) def cari(self.keyPressEvent( e ) def enter(self): self.Key_Enter]: self.reject() else: self.312 BAB 23.seek(brs) data = self.seek( self.upper() if awalan: ketemu = t. w): if self.accept() def escape(self): if self.cari() < 0 and self._field ) t = QString(data).currentRow() ) self.isEmpty(): self.teks.teks.Key_Return.text().find(QRegExp("^"+s)) > -1 . mulaiBaris=-1): s = "%s" % self.enter() else: self.text().key() in [Qt.text(). DATABASE 28| 29| 30| 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| 41| 42| 43| 44| 45| 46| 47| 48| 49| 50| 51| 52| 53| 54| 55| 56| elif e.warning(self.tabel.clear() def teksBerubah(self.teks.upper() brs = mulaiBaris ketemu = 0 while brs < self.cari(0) < 0: QMessageBox._cursor.tabel.strField( self.isEmpty(): return if self. "%s tidak ditemukan" % self.

isOpen(): 75| c = QSqlCursor( "barang" ) 76| fm = FormCari(None.value().5. self.tabel.currentRow() != brs: 60| self.20) 80| fm.teks.tabel.Upper) 79| fm.isEmpty(): return 66| if self. c.setColumnWidth(1. "nama" ) 77| fm.field("id").setCase("nama".tabel.setCurrentCell(brs.tabel. self.kolomCari) 61| return brs 62| return -1 63| 64| def lanjut(self): 65| if self.200) 78| fm.showMaximized() 81| fm._cursor.toInt() .tabel.Accepted: 83| print fm.text().currentRow() ) < 0: 67| self.exec_loop() 82| if fm.setMaxLength("nama".db.cari(0) 68| 69| 70| if __name__ == "__main__": 71| from login import FormLogin 72| 73| app = QApplication([]) 74| if FormLogin(None).result() == QDialog. LineCase.23.tabel.find(s) > -1 58| if ketemu: 59| if self.cari(0. CARA LAIN MENANGANI TABEL 313 57| else: ketemu = t.

Bila tabel barang sudah terisi. Namun cara ini tidak dianjurkan karena semakin banyak record semakin lama proses pencarian nilai maksimum. maka solusi nomor urut (autoincrement) bisa menjadi pilihan. Misalkan diperoleh angka 142. nomor INTEGER NOT NULL).314 BAB 23. maka isilah tabel urutan dengan query berikut: INSERT INTO urutan(tabel. CREATE TABLE urutan( tabel VARCHAR(32) NOT NULL PRIMARY KEY.142). Namun bila masih kosong gantilah dengan angka 0.7 Nomor Urut . SELECT MAX(id) FROM barang.Autoincrement Bila Anda menginginkan kode barang sekedar kode. beforePost() .nomor) VALUES ('barang'. DATABASE 23. Sebagai gantinya dibuatlah sebuah tabel untuk mencatat nomor terakhir. Artinya pemakai tidak perlu mengisikan kode barang karena akan diisi secara otomatis sesuai dengan nomor urut terakhir. dapatkan nomor terakhirnya dengan MAX().5. Untuk mendapatkannya gunakan fungsi MAX() pada SQL. Event ini bisa kita dapatkan pada yang memang disediakan untuk validasi tamba- sesaat han. Selanjutnya nomor urut ini akan dimasukkan pada eld id sebelum disimpan.

tabel.200) 11| self.beforePost 18| self.status == self.setFocus() 23| self.tabel.barang.setCase("nama". cursor): 22| self.23.tabel.nama = "" 20| 21| def afterInsert(self.tabel.next() 16| self. LineCase.5.afterInsert = self. parent): 08| self.value("nomor").currentRow().afterPost 19| self. QSqlIndex 03| from caritabel import FormCari 04| from linecase import LineCase 05| 06| class FormBarang(FormCari): 07| def __init__(self.tabel.__init__(self.setColumnWidth(1.urutan.toInt() + 1 .20) 13| self.afterInsert 17| self.barang = QSqlCursor("barang") 09| FormCari. "nama") 10| self.select("tabel='barang'") 15| self.tabel. self. CARA LAIN MENANGANI TABEL 315 barang.urutan = QSqlCursor("urutan") 14| self.beforePost = self. parent.Upper) 12| self.afterPost = self.py --------01| from qt import * 02| from qtsql import QSqlCursor.setMaxLength("nama".urutan. cursor): 26| if self.tabel.tabel.tabel.1) 24| 25| def beforePost(self.Insert: 27| n = self.urutan.tabel.setCurrentCell(self.tabel.

setValue("nomor".teks.\ 35| toString() 36| 37| def afterPost(self. QVariant(n)) 29| b = self.setFocus() 40| self.urutan.teks. QVariant(n)) 31| self.urutan.setValue("id".urutan.db.nama = cursor.exec_loop() .next() 34| self.setText( self.316 BAB 23.update() 32| self.teks.nama ) 39| self. cursor): 38| self.editBuffer().urutan.showMaximized() 49| fm.select() 33| self. DATABASE 28| cursor.editBuffer().primeUpdate() 30| b.isOpen(): 47| fm = FormBarang(None) 48| fm.value("nama").selectAll() 41| 42| 43| if __name__ == "__main__": 44| from login import FormLogin 45| app = QApplication([]) 46| if FormLogin(None).

sehingga kita perlu mendaftarkan nilai terakhirnya dalam 317 .Bab 24 Kasir III Karena sudah masuk tema database. Kasir III akan dilengkapi tur untuk menyimpan transaksi penjualan. Tabel pertama bernama penjualan yang berisi header transaksi: CREATE TABLE penjualan( id INTEGER NOT NULL PRIMARY KEY.1 Struktur Tabel Transaksi disimpan dalam dua tabel. 24. wkt DATETIME NOT NULL). id merupakan identitas transaksi. Field ini bersifat autoincrement.

KASIR III urutan: INSERT INTO urutan (tabel. yang menjadi referensi harus merupakan primary key di tabel . Namun struktur ini bisa jadi memiliki kelemahan. REFERENCES. Baik id_penjualan maupun id_barang dikatebegitu pula dengan gorikan sebagai foreign key. Nilai id_penjualan harus terdaftar pada eld id di tabel penjualan. Berbeda dengan tabel-tabel sebelumnya. id_barang) ). id_barang harus terdaftar pada eld id di 1 Hal ini ditunjukkan dengan adanya perintah tabel barang. yaitu tanggal dan jam transak- Sedangkan tabel kedua berisi rinciannya. tabel penjualan_barang memiliki dua eld sebagai primary key.318 BAB 24. yaitu daftar barang yang dijual: CREATE TABLE penjualan_barang( id_penjualan INTEGER NOT NULL REFERENCES penjualan(id). Ini artinya dalam sebuah transaksi tidak boleh tercatat dua barang yang sama di dua record. id_barang INTEGER NOT NULL REFERENCES barang(id). jumlah FLOAT NOT NULL. harga FLOAT NOT NULL. yaitu id_penjualan dan id_barang. 0). tabel dan si. nomor) VALUES ('penjualan'. Misalkan ada penjualan dua 1 Field referensi. PRIMARY KEY (id_penjualan. wkt adalah waktu transaksi.

PRIMARY KEY (id_penjualan.2. 24. harga FLOAT NOT NULL. Jadi kita tambahkan saja sebuah eld bertipe integer namun dengan ukuran yang lebih kecil. Tentu saja kita tidak ingin mencatatnya sebagai sebuah semangka dengan berat 7 kg karena ini bisa membuat kekeliruan dalam menghitung banyaknya barang. DAFTAR BARANG 319 buah semangka dengan berat masing-masing 3 dan 4 kg.2 Daftar Barang Kasir III memanfaatkan Form Barang untuk mencari ID barang. yaitu SMALLINT. jumlah FLOAT NOT NULL.24. nomor SMALLINT NOT NULL. nomor) ). maka bisa dihapus dengan perintah berikut: DROP TABLE penjualan_barang. Field nomor merupakan nomor urut per transaksi yang akan diisi otomatis (autoincrement). . id_barang INTEGER NOT NULL REFERENCES barang(id). lalu buat kembali: CREATE TABLE penjualan_barang( id_penjualan INTEGER NOT NULL REFERENCES penjualan(id). Membuang primary key juga tidak dianjurkan karena hanya membuat tabel tersebut hanya bisa di-INSERT. sekaligus untuk menambah data barang baru atau mengubah 2 Jangkauan SMALLINT adalah -32767 hingga 32767.2 Kalau sudah terlanjut mem- buat tabelnya.

1: Kasir harga. karena pencetakan diserahkan sepenuhnya pada sistem operasi. 24. tidak peduli pencetakan berhasil atau tidak.4 Pencetakan Struk disimpan ke sebuah le yang telah ditentukan lokasinya. data tidak langsung dimasukkan dalam tabel. pemakai sudah dapat memasukkan data kembali. Huruf tersebut memicu tampilnya Form Barang sekaligus menyertakan huruf tadi. KASIR III Gambar 24. Setelah pembayaran (mencetak struk) baruTeknik ini diambil karena pertimbangan lah data disimpan. melainkan ditampung terlebih dahulu.3 Penyimpanan Data Pada saat pemakai mendata barang yang dibeli pelanggan. Untuk struk yang cukup panjang dengan antrian pembeli yang juga panjang hal ini tentu sangat menghemat waktu. kecepatan layanan pada para pelanggan. . 24. Meski program ini mewajibkan penggunaan printer. namun ketiadaannya tidak menghalangi proses pemasukan data. Pada saat printer mencetak. untuk kemudian dicetak ke printer. Untuk menampilkannya cukup menekan tombol huruf A-Z.320 BAB 24.

5.tombolDitekan = None 015| 016| def keyPressEvent(self.tombolDitekan( e ) 018| 019| # Kursor / Focus control tetap di sini 020| def focusOutEvent(self. parent) 013| self.setValidator( QDoubleValidator(self) ) 014| self.py --------001| from qt import * 002| from qtsql import QSqlCursor. QSqlQuery 003| from waktudigital import WaktuDigital 004| from valuegrid import ValueGrid 005| from barang import FormBarang 006| from fungsi import ribu 007| from string import rjust. .__init__(self. parent): 012| QLineEdit. WaktuDigital. PROGRAM 321 24.tombolDitekan: self.24.setFocus() 3 Lihat source-nya pada halaman 143. e): 021| self.3 kasir3. ljust 008| import os 009| 010| class LineControl(QLineEdit): 011| def __init__(self.5 Program Agar form lebih informatif. program ini juga menyertakan Silahkan ubah font-nya apabila dianggap terlalu kecil. e): 017| if self.

Qt. parent): 032| QDialog.setAutoAdd(1) 036| jam = WaktuDigital(self) 037| self.setCaption("Kasir III") 034| layout = QVBoxLayout(self) 035| layout. 029| Qt.hideColumn(0) # id barang 045| self. KASIR III 022| 023| 024| class FormKasir(QDialog): 025| Huruf = range(ord("A").Flat 039| self.horizontalHeader().horizontalHeader().setNumDigits(10) 041| self.tabel = ValueGrid(self) 043| self. parent) 033| self.brg = QSqlCursor( "barang" ) 050| self.horizontalHeader().setMinimumHeight(150) 040| self. Qt.Key_PageDown.Key_PageUp.setLabel(2.ord("z")+1) 027| GridKeys = [Qt.322 BAB 24. 048| self.lcd.tabel.setNumCols(4) 044| self. 028| Qt.Key_Down.tabel.setLabel(1.teks = LineControl(self) 042| self.setSegmentStyle( QLCDNumber.tabel.__init__(self.lcd.lcd = QLCDNumber(self) 038| self. 047| self. 046| self.setLabel(3.fmBrg = FormBarang(self) 049| self.lcd.ord("Z")+1) 026| Huruf = Huruf + range(ord("a").Key_Up.tabel.tabel.Key_Delete] 030| 031| def __init__(self.urutan = QSqlCursor( "urutan" ) ) "Nama") "Jumlah") "Harga") .

e): if e.bayar() elif e.100) def reset(self): . e ) def resizeEvent(self.Key_Enter]: self.text() ) elif e.teks.24.output = "/tmp/kasir.tabel.tabel.key() in [Qt.tabel.currentRow() == \ self.tabel.formBarang( e.Key_Asterisk: self. self.query = QSqlQuery() self.width() self.tabel.tombolDitekan = self.columnWidth(2) self.key() == Qt. PROGRAM 051| 052| 053| 054| 055| 056| 057| 058| 059| 060| 061| 062| 063| 064| 065| 066| 067| 068| 069| 070| 071| 072| 073| 074| 075| 076| 077| 078| 079| 323 self.keyPressEvent( e ) else: QLineEdit.select( "tabel='penjualan'" ) self.ascii() in self.tabel.key() == Qt.tabel. Qt. e): self.numRows()-1: return self.beforeDelete def tombolDitekan(self.ubahJml() elif e.Huruf: self.tabel.cariKode() elif e.keyPressEvent( self.clear() elif e.GridKeys: if e.txt" self.Key_Down and \ self.key() == Qt.key() == Qt.columnWidth(3) .Key_Return.beforeDelete = self.reset() self.teks.urutan.5.teks.Key_Escape: self.setColumnWidth( 1.key() in self.tombolDitekan self.Key_Plus: self.

total)) def cariKode(self): where = "id='%s'" % self.lcd.tambah( self.teks.perluReset = 0 def ubahJml(self): try: self.text() self.total .display(0) self.clear() def beforeDelete(self.tabel.lcd.jml = round(self.self.brg.total = self.text() ) self.data[row][3] self.select(where) if self.teks.total = 0 self.setData([]) self.tabel. cursor): .teks.display(self.brg ) else: self. row): self.lcd. KASIR III 080| 081| 082| 083| 084| 085| 086| 087| 088| 089| 090| 091| 092| 093| 094| 095| 096| 097| 098| 099| 100| 101| 102| 103| 104| 105| 106| 107| 108| self.teks.next(): self.jml = float(str(self.clear() self.pesan( "Kode barang %s tidak ada" % \ self.jml = 1.display(ribu(self.teks.324 BAB 24.jml*100)/100 self.brg.teks.jml) self.text())) except: return # dua desimal saja self.0 self.selectAll() def tambah(self.

data. e): self.24.jml ) rec.0 def timerEvent(self.clear() self.toDouble() ) self.total)) rec = [] rec.tabel.total + harga self.toString()) ) rec.append( self.showMaximized() # Bila data yang dicari terlalu ke bawah.data: self.tabel.reset() harga = int( self.5. huruf dimasukkan untuk .value("nama")._teks = teks # untuk timer self.teks. PROGRAM 109| 110| 111| 112| 113| 114| 115| 116| 117| 118| 119| 120| 121| 122| 123| 124| 125| 126| 127| 128| 129| 130| 131| 132| 133| 134| 135| 136| 137| 325 if self.append( list(rec) ) self.data[row] = list(rec) else: self.display(ribu(self.fmBrg. current # record tidak tampak.append( cursor.value("id").turun() row = self.jml * cursor. Timer digunakan agar pada # saat form barang tampil.teks.lcd.tabel.perluReset: self.repaintContents() self.tabel. teks): self._teks ) def formBarang(self.tabel.jml = 1.total = self.value("harga").append( harga ) if self.fmBrg.append( str(cursor.setText( self.currentRow() self.toInt() ) rec.killTimers() self.tabel.

execQuery( "SELECT NOW()" ): return self.urutan.urutan.lcd.self.next() . KASIR III 138| 139| 140| 141| 142| 143| 144| 145| 146| 147| 148| 149| 150| 151| 152| 153| 154| 155| 156| 157| 158| 159| 160| 161| 162| 163| 164| 165| 166| # dicari.326 BAB 24.teks.total) self.result() == QDialog.fmBrg.clear() # Header self.text()) return k = int(b .exec_loop() if self.query.urutan.text()))) except ValueError: self.display(ribu(k)) self.teks._cursor ) def bayar(self): try: b = int(float(str(self.execQuery( sql ): return # Antisipasi multiuser.pesan("%s bukan angka" % self.select() self.startTimer( 500 ) self.teks.fmBrg. self.tambah( self. menghindari perbedaan setting # tanggal antar komputer client if not self. tanggal mengambil # dari database.toInt()+1 sql = """UPDATE urutan SET nomor=%s WHERE tabel='penjualan'""" % id_penjualan if not self.fmBrg.next() id_penjualan = \ self.Accepted: self.value("nomor").

jml.ISODate) ) if not self.struk.24. harga = rec daftarSql.cetakAkhir( "BAYAR". nomor. jml. self.5.query.data: nomor = nomor + 1 kode.execQuery( sql ): return for sql in daftarSql: if not self. %s. PROGRAM 167| 168| 169| 170| 171| 172| 173| 174| 175| 176| 177| 178| 179| 180| 181| 182| 183| 184| 185| 186| 187| 188| 189| 190| 191| 192| 193| 194| 195| 327 tgl = self.execQuery( sql ): return . kode. harga) VALUES (%s. k ) self. nama.cetakAkhir( "KEMBALI".toDateTime() self. "-" * 35) self.cetakFile() self. %s)""" % \ ( id_penjualan. %s. "-" * 35 ) # Cetak nomor = 0 daftarSql = [] for rec in self. tgl.toString(Qt. harga ) ) self.struk = "%s%s\n" % (self.value(0). jumlah. id_barang.perluReset = 1 # Simpan ke database sql = """INSERT INTO penjualan (id. nomor.tabel. harga ) self.struk = "%s\n%s\n" % ( tgl.append( """INSERT INTO penjualan_barang (id_penjualan.toString("dd-MM-yyyy hh:mm"). %s.'%s')""" % ( id_penjualan. jml. tgl) VALUES (%s.cetakAkhir( "TOTAL".total ) self. b ) self.cetakBarang( nama.

s) def execQuery(self. "w") f. total): self. ljust(nama[:20]. 7). KASIR III 196| 197| 198| 199| 200| 201| 202| 203| 204| 205| 206| 207| 208| 209| 210| 211| 212| 213| 214| 215| 216| 217| 218| 219| 220| 221| 222| 223| 224| def pesan(self. rjust(ribu(subtotal).struk = "%s%s%s\n" % ( self.struk.query. 20).pesan ( "%s\n%s" % ( self. s): QMessageBox.struk.25) ) def cetakFile(self): s = "%s\n%s%s" % (chr(15).write(s) f. nama.10).system("cat %s > /dev/lp0 &" % self.close() os.328 BAB 24. "Perhatian". rjust(ribu(jml). sql): ok = self. rjust(ribu(total).struk. ljust(nama.output) .output.warning(self.query.lastQuery() ) ) def cetakBarang(self.query.execQuery( sql ) if ok: return ok else: self. subtotal): self. "\n"*7) f = open(self.8) ) def cetakAkhir(self. nama.system("killall cat") os. jml.lastError(). self.databaseText().struk = "%s%s%s%s\n" % ( self. self.

QDateTime. DBGrid tidak menampilkan current record sebelum form-nya tampil.exec_loop() Ada yang menarik dalam program ini dimana merupakan pusat kendali.showMaximized() 233| fm.isOpen(): 231| fm = FormKasir(None) 232| fm.ISODate membuat killTimers(). Tugasnya adalah memasukkan huruf ke dalam teks pencarian agar current record berada pada nama awal barang yang dicari. PROGRAM 225| 226| 227| if __name__ == "__main__": 228| from login import FormLogin 229| app = QApplication([]) 230| if FormLogin(None). Event klik 329 LineControl focusOutEvent() membuat- nya selalu menjadi pusat perhatian. Oleh karena itu dibutuhkan petugas lain yang bekerja beberapa saat setelah form tampil. Ketemu atau tidak selanjutnya timer tidak dibutuhkan lagi dengan memanggil fungsi Penggunaan timer pada program ini merupakan trik kare- Qt. tanggal. bulan. Latihan Tambahkan nama toko dalam header struk. Pola ini dibutuhkan dalam perintah SQL untuk menerima masukan eld waktu. Padahal untuk menampilkan form dibutuhkan exec_loop() yang akan membuat proses terhenti hingga form ditutup. tetap saja kurLineControl. Nama . jam.5.24.toString() menampil- kan format waktu sesuai standar ISO. yaitu berturut-turut: tahun. dan detik. menit.db. Jadi meski Anda mengsor berada di na ValueGrid untuk mengalihkan fokus kursor.

tentunya.id . SELECT b. barang b.nama.330 BAB 24. Laporan ini kerap dibutuhkan untuk analisa bisnis guna meningkatkan kualitas layanan dan juga kuantitas penjualan .6 Laporan Ada beberapa laporan yang dapat dibuat berdasarkan struktur tabel yang ada. Bila Anda berniat untuk membuat program tampilannya. 24. sehingga para pemakai mendapat keleluasaan menentukan periode: harian. Periode ini berupa dua masukan tanggal: awal dan akhir. Manfaatnya adalah untuk memprioritaskan pengadaan barang tertentu yang paling sering dibeli pelanggan. bulanan. COUNT(*) FROM penjualan_barang pb.id GROUP BY 1 ORDER BY 2 DESC. KASIR III toko ini tersimpan dalam database. mingguan.id_barang = b. penjualan p WHERE pb. biasakan menyertakan periode transaksi. 24.id_barang = b. tahunan. dsb.nama.6. barang b WHERE pb. Contoh: SELECT b. COUNT(*) FROM penjualan_barang pb.1 Barang Terlaris Laporan ini menampilkan nama barang dengan urutan mulai dari yang terlaris.

id_penjualan = p. SUM(pb. AVG() sebagai pengganti SUM() pada .id_penjualan GROUP BY 1 ORDER BY 1.id_penjualan GROUP BY 1 ORDER BY 1. LAPORAN 331 AND pb.harga) FROM penjualan p. sedangkan dalam MySQL: SELECT FROM_DAYS(TO_DAYS(p. Berikut ini perintah dalam PostgreSQL: SELECT date(tgl).6. Option DESC (descending ) digunakan untuk mengurutkan data dari yang nilainya paling tinggi ke yang paling kecil. 24. SUM(pb.harga) FROM penjualan p. 24.6.3 Rata-rata Penjualan Harian Laporan ini bisa digunakan untuk mengukur pangsa pasar dari sudut potensi pelanggan atau kalau boleh dikatakan sebagai daya beli.tgl)).6.id = pb.24.id = pb.tgl BETWEEN '2003/2/1' AND '2003/2/28') GROUP BY 1 ORDER BY 2 DESC.2 Total Penjualan Harian Laporan ini menampilkan tanggal transaksi beserta total nilainya. penjualan_barang pb WHERE p. Gunakan fungsi contoh di atas.id AND (p. penjualan_barang pb WHERE p.

COUNT(*) FROM penjualan GROUP BY 1 ORDER BY 1 DESC.6. KASIR III 24.332 BAB 24. Bisa digunakan sebagai acuan untuk mempersiapkan tenaga tambahan guna menghindari antrian panjang. .4 Jam Sibuk Untuk mengetahui jam-jam kepadatan pembeli jalankan perintah berikut: SELECT EXTRACT(HOUR FROM tgl).

O'Reilly.qt. www.Referensi Teknis. www.co. 1996 [3] http://groups.Bibliogra [1] Sugiana. www. Owo.org [10] MySQL.com/group/id_python/les/pytut.riverbankcomputing. Jakarta.org 333 .postgresql. www. ta.html [4] Sugiana. Aplikasi Rumah Sakit Pertamina Jaya . Mark.kde.yahoo. Jakar- Programming Python. Pemrograman Dasar dengan Python.org [8] KDE.uk/pyqt [6] Python.mysql. www.org [7] Qt. 2001 [2] Lutz.id. Owo.python. www. 2000 [5] PyQt.org [9] PostgreSQL.

org [13] Infolinux.redhat.334 BIBLIOGRAFI [11] RedHat. www.infolinux. www.linux. www.com [12] Linux.co.id .

Indeks * perkalian. 39 + penjumlahan. 140 addMonths(). QLabel.pengurangan. 39 . QDate. bilangan acak. keyboard. 165 __init__(). 61 __init__(). dokumentasi. 184 addDays(). 160 addColumn(). 152 accept(). 61 accept(). 140 addDays(). QCloseEvent. 162. QDate. 95 acak. QLayout. QSqlDatabase. 91 &. QDate. 39 / pembagian. 145 activateNextCell(). QTable. 143 addSecs(). 139 addStretch().string formatting. 74 Alt. QDateTime. 132 addYears(). 24 and. 137 addWidget(). 160 __name__. QGridLayout. 84 __init__(). QDataTable. 114 __doc__. 55 angka(). 193 335 addDatabase(). 117 analyst. QDateTime. 140 addYears(). QDateTime. 198 . 143 addMonths(). QTable. QDateTime. 39 % . Grid. 143 addSecs(). QBoxLayout. 134 addWidget(). 38. QDialog. 143 akar. QTime. 39 ** pangkat.

sinyal QPushButton. 43 cat. 157 cell. 85 cast. font. bahasa library Qt. 62 buer pada QSqlCursor. tipe data. QSqlQuery. associative array. 71 Arial. 161. 71 at(). 197 . 41 bahasa pemrograman. 44 argv. 51 blue. 47 beginEdit(). QComboBox. 152 cell. 98 BMP. 71. 70. 96 boolean. QCheckBox. 24 bold. font. QTable. 157 cellWidget(). 72 checkbox. QTextEdit. 70. QTable. 21 black. QWidget. 93 capslock. 166 chdir(). 71 clear(). 105 ASCII. QCheckBox. QComboBox. 167 backslash. list. 105 autowarp. 226 background. elemen QTable. QSqlField. 152 combobox. 197 clearCell(). 96 array. 24 C. 18 baris. 18. 121 closeEvent(). 55 caption. 93 clear(). 98 break. 22 C++. 89 chmod. 210 Belanda. list dua dimensi.336 INDEKS bug. 48 array. QComboBox. QTable. 18. QComboBox. Python antarmuappend(). 98 blok program. current cell. 89 AVG(). sinyal QButtonGroup. 99 child. 102 clicked(). 189 clicked(). 99 checked. SQL. 166 clearEdit(). 22 ascending. 70 chr(). 93 antarmuka. 190 autocompletion. le. 22 C++. 105 ka C. 93 close().

QDate. 166. QDate. text editor. 140 . QDate. keyboard. 98 database. karakter. 139 CursorTable. 185 createEditor(). QButtonGroup. 96 CREATE DATABASE. 226 day(). 98 darkCyan. 225 Courier. 117 count(). 161 currentText(). 98 darkMagenta. font. QTable. 140 dayOfYear(). 106. QDateTime. 157 currentColumn(). 179 databaseText(). 106 currentTime(). 210 cross. 76 current column. 29 constructor. 184 date(). SQL. QTable. QObject. QSqlError. 142 337 currentDateTime(). 98 darkYellow. 161 currentDate(). QComboBox. 189 currentRow(). 180. 194 cyan. QDatecurrentItem(). 140 dayOfWeek(). 28 connect(). 179 console. 140 Time. 98 darkRed. 98 darkGreen.INDEKS command line. 189 current row. QTable. 179 database server. QTime. 98 darkGray. 98 darkBlue. 149 Courier. QTable. 142 DATETIME ke DATE. 102 COUNT(). 157 currentChanged(). 181 CREATE TABLE. 157 current directory. SQL. SQL. 93 connection ID. class. 123 Control. QComboBox. 72 console environment. QTable. 121. SQL. QTable. 72 current record. 35 CSV. 185 database le. 84 container. QDate.

110 enter. info properti modul. info properti objek. 161 exec__loop(). 189 extensible. 199 delRecords().338 INDEKS double-click. 74 exception. 224 execQuery(). 117 event driven programming. QSqlCursor. QLCDNumber. 185 Delphi. 53 embeddable. Borland. 168 driver. QDate. 140 daysInYear(). manfaat. QComboBox. 199. 24 def. 168 drawText(). 166 editBuer(). 24 debugging. 140 daysTo(). class. 42 debugging. 61 dir(). 168 error. 112 dokumentasi modul. 50 direktori aktif. 218 edit-mode. 224 debugging. 76 . 91 except. 61 dokumentasi. 69 Enter. 66. 70 dir(). QDialog. QPainter. SQL. 22 daysInMonth(). 53 else. 105 esien. 22 enable. QDate. 28 dotmatrix. list. 44 DELETE. 94. 72 disable. QDate. SQL. 63 deklarasi variabel. 40 development cycle. 24 DOS Prompt. 143 DBGrid. 179 driver database. 141 daysTo(). 73 exec(). QPainter. 73 event. dictionary. QTable. pada QComboBox. 84 exec_loop(). 197 descending. keyboard. proses. QSqlQuery. 23 elif. karakter. QSqlCursor. 107 drawLine(). 35 del. 49 del. 105 desimal. QPainter. 197 editor. QDateTime. 110 display(). 179 DROP TABLE. 115 eraseRect(). 18 device. arti.

64 fungsi. 84 339 form manager. 197 eld. bilangan ganjil. 93 fungsi.INDEKS EXTRACT(). 23. 29 gras. QFileDialog. QSqlQuery. 154 getOpenFileName(). 123 fungsi. tipe data. SQL. 70 font(). QApplication. 59 form. locale. 72 getDouble(). integer ke oat. perulangan. 47 le. 91 frame. in range(). QSqlRecord. rekursif. 158 focused. SQL. 121 le. 60 for. string. 76 le. 224 font printer. QInputDialog. QButtonGroup. 154 getInteger(). fungsi. 121 le. ush(). 29 getcwd(). nilai masukan. 76 GRANT. 43 oat. 76 eld. 226 faktorial. 173 rst(). list dua dimensi. QWidget. 121 nd(). write(). string ke oat. 37 ush(). 121 focus widget. xed. 148 getSaveFileName(). 97 font. bilangan. 61 for. modus gras. 55 gedit. nilai keluaran. QInputDialog. close(). 84 format(). 97 for di dalam for. 64 fungsi. perbandingan. QFileDialog. 60 for. 69. 190 oat(). 40 formatting. 110 focusOutEvent(). penyisipan. 38 oat(). 60 faktorial. 148 getText(). QInputDialog. le teks. 154 Gnome. 149 fonts. 65 false. 191 . QWidget. daftar font pada kwrite. 52 eld(). 102 nd(). QString. 65 ganjil. le.

dictionary. 72 intValue(). 152 in. 54 indent. QTable. 51 ignore(). 189 . 160. string ke QDateTime. 78 height(). 23. Python: C interface. 35 interface. 43. 21 halaman. 40 int(). QTime. 108 insertRows(). 106 insertTab(). 70 icon. 166 insertStrList(). string ke integer. QString. tipe data. Qt. QComboBox. 165 Grid. Internet Protocol. 149 if. 29 int(). 117 IP. SQL. SQL. 59 in. 179 isChecked(). 70 has_key(). QTabWidget. 198 GROUP BY. 41 input. QTable. 18. 129 install. 117 horizontalHeader(). QRect. QLCDNumber. exec(). operator. 66 interpreter. 139 huruf. 34 Indonesia. QCloseEvent. for. 225 italic. 167 home directory. __init__(). ganti halaman. QLineEdit. QCheckBox. 139 Java. 161. 157. 93 internet. font. 96 highlight. 156 hour(). font. ukuran. 225 Guido. 111 ISODate. 100 isEmpty(). 55 integer. 88 insert(). 21. QComboBox. 22 interpreter. 168 Helvetica. pembulatan. 44 INSERT. 98 Grid. 22 gray. list. 96 jam(). class. 37 interactive interpreter. 98 green.340 INDEKS insertItem(). aturan penulisan. 51 interactive mode. 21. 185 insertItem(). lingkup sys. QListBox. 199 jam. QTime.

QWidget. QSqlDatabase. 43 library. 70 margin. 21. 71 karakter. 49 killTimers(). bentuk logika. 84 lp0. 189 kutip tunggal. 33.INDEKS JPEG. modul. 47 konversi. karakter. database server. teksBerubah. jumlah elemen list. 173 list(). interactive mode. 98 larik. QObject. 96 linecase. contoh. 131 kwrite. kesalahan. 41 kwrite. 34 . 152 lp0. 24 kalkulator. kesalahan logika. 35. 117 keypad. 114 kalkulator. 27. modul. class. 225 kolom. aturan penulisan. 29. melihat daftar font. 165. 96 kate. 45 len(). 59 looping. string ke oat. 52. font. 40 logika. 29 KDE. 184 len(). 224 Linux. 155. 29. 55 logika. 81. 96 LineCase. 95. nama lain list. menyalin isi list. 43 kutip ganda. 179 loop. 98 LineCase. QSqlQuery. 97 magenta. panjang string. 55 konversi. 47. QKeyEvent. karakter. 22 layouter. 81 lightGray. 180 list dua dimensi. dictionary. 38 karakter ASCII. 113 key(). 43 last(). 78 locale. 94 LineCase. 66 kalkulator. printer. 95 LineControl. 115 keyPressEvent(). 131 341 lastError(). string. 117 keys(). 48 ljust(). 73 login. list dua dimensi. event teksBerubah. 190 maintenance. 41 kutip tunggal pada query. 93.

190 non-visual class. 89 math. modul. 181 MySQL. 166 pecahan. 39 option.342 INDEKS objek. 37 . 45. 189 or. 38 MAX(). 213 memori. 71. 71 os. 94 owner. 34 pass. 65 None. SQL. MySQL client. 60 multiline. 56 Oracle. alokasi memori. QWidget. 21 object oriented programming. 88 multiuser. 18 Pascal. bilangan pecahan. 89 parent. bahasa pemrograman. 140 mouse. 179181 mysql. QTable. berorientasi objek. 185 NULL. 71 override. rekursif. QTime. QDate. 179 msec(). 179 open(). 197 object oriented. nilai keluaran fungsi. 166 panel. SQL. 65 not. SQL. 185. istilah. 139 month(). 72 out of paper. 99 Pascal. 139 multidimensi. 179 ord(). objek hampa. 25 optional. 23 objek. 23 objek-tampak. 65 minute(). 87 ODBC. 84 paintCell(). tipe data. list. 69 OpenGL. 181. 161. font dan warna. 55 NOT. 18 operator bilangan. logika false. 113 MS-SQL. 21. le. 123 parent. perbandingan. 90 None. 24 memori. modul. QSqlQuery. QTime. 52 None. 189. 193 next().

105 postgres. 193 QApplication. 33. PostgreSQL client. superuser PostgreSQL. 84 PyQt. sejarah nama. 180 prev(). 18 Python. setMainWidget(). 210 primeDelete(). 23 Perl. pada QComboBox. 34 pico. tanpa enter. 21 Python. dengan Qt. 22 Python . 136. berorientasi objek. setDirection(). 91 printer. 22 Python. 197 primeInsert(). 91 pointer. 81 Python. addStretch(). 29 plaintext.C++. 136 . 22 PHP. 134. dokumentasi. 36 Python. bahasa pemrograman. QSqlCursor.Perl. 69 print. 70 programmer. 179. QSqlCursor. 197 print. alasan memilih. perbandingan bahasa. 190 PRIMARY KEY. 180 PostgreSQL. perbandingan. SQL. 36 print. 197 primeUpdate(). 23 Python. interactive interpreter. 185. 180.INDEKS pedoman menulis program. 134 QBoxLayout. 191 Python . 24 psql. 22 Python. 93 QApplication. 93 python. 23 Python. 83. 22 Python . 83 QBoxLayout.Java. text editor. 76 popup-list. QSqlCursor.Tcl. QSqlQuery. 81 343 Python . 137 QBoxLayout. 30 PytQt.menampilkan QString.

141 QDate. setAutoCompletion(). 100 QCheckBox. 193 QDate. month(). 123 QButtonGroup. 106 QDataTable. currentItem(). 140 QDate. 140 QDate. daysInYear(). addYears(). day(). addYears(). year(). dayOfYear(). insertItem(). 140 QDate. 141 QDate. 140 QDate. 106 QComboBox. 140 QDate. pedoman. 140 QDate. ignore(). addColumn(). selected(). setSqlCursor(). addSecs(). addMonths(). pedoman.344 INDEKS QComboBox. 102 QButtonGroup. 189 QComboBox. 140 QDateTime. daysInMonth(). currentText(). 106 . nd(). 140 QDate. addDays(). 143 QDateTime. 100 QCloseEvent. 142 QBrush. 106 QComboBox. 143 QDateTime. 101. daysTo(). 189 QComboBox. 192194 QDataTable. 142 QDateTime. 189 QComboBox. 189 QComboBox. 102 QButtonGroup. setEditable(). text(). clicked(). addMonths(). 104 QCheckBox. warna. 140 QDate. 106 QComboBox. clearEdit(). accept(). setButton(). 121. removeItem(). 105 QComboBox. 106 QComboBox. 152 QColor. 152 QCloseEvent. count(). insertStrList(). currentDate(). setStyle(). 140 QDate. isChecked(). toString(). 167 QBrush. 140 QDate. setColor(). 102 QButtonGroup. 106. 143 QDateTime. 140 QDate. currentDateTime(). 167 QButtonGroup. 99 QCheckBox. 102 QButtonGroup. 193 QDataTable. 143 QDateTime. 98 QComboBox. addDays(). dayOfWeek().

pada QTable. 166 QLineEdit. toString(). setBuddy(). 117 QKeyEvent. 111 QLCDNumber. 131. setItalic(). setPointSize(). textChanged(). 111 . 132 QLayout. 136. 132 QLayout. setBold(). state(). 97 QFont. 97 QFont. getInteger(). 98 QLabel. addWidget(). key(). intValue(). 98 QFont. date(). time(). 96 QFont. 137 QHBoxLayout. setUnderline(). 145 QDialog. text(). 89 QLabel. 121. setAutoAdd(). 148 QFileDialog. 137 QGridLayout. 126 QDialog. 154 QInputDialog. 88. setAutoResize(). getSaveFileName(). addWidget(). 160 QLineEdit. 89. 145 QDialog. 117 QLineEdit.INDEKS QDateTime. 224 QDialog. 156 QInputDialog. 154 QInputDialog. getDouble(). display(). getText(). 105 QLineEdit. 154 QKeyEvent. setValue(). 146 QFileDialog. daysTo(). 98 QFont. result(). 123 QGridLayout. 112 QLCDNumber. 117 QKeyEvent. 137 QLCDNumber. 143 QDateTime. accept(). setSpacing(). setFamily(). 146 345 QHeader. 114 QLayout. 117 QLabel. 142 QDateTime. reject(). 126 QDial. exec_loop(). 134 QInputDialog. 145 QDialog. 131. 117 QLCDNumber. setLabel(). secsTo(). 137 QLayout. 143 QDateTime. 98 QFrame. setMargin(). 148 QFont. pada QComboBox. 145 QFileDialog. 88. 117 QKeyEvent. getOpenFileName(). value(). 137 QLayout. 142 QDateTime. 225 QDial. 98.

197 QSqlCursor. setPen(). primeInsert(). 168 QRect. 197 QSqlCursor. 168 QPainter. height(). 168 QPainter. 197 QSqlCursor. setRight(). 168 QPen. primeDelete(). 168 QRect. 143 QObject. 146. 108 QListBox. 197 QSqlCursor. 168 QRegExp. width(). setChecked(). valueChanged(). repaintContents(). 197 QSqlCursor. 108 QMessageBox. drawLine(). removeItem(). insertItem(). 167 QSpinBox. editBuer(). delRecords(). setColor(). timer. 168 QRect. 126 QSqlCursor. startTimer(). setX(). 108 QListBox. setValue(). killTimers(). 89. 173 QScrollView. 168 QRect. 168 QRect. 192 QSqlDatabase. 167 QPushButton. setBottom(). 168 QRect. y(). 88. 191 QSqlCursor. 191 QSqlCursor. primeUpdate(). 126 QSpinBox. drawText(). selected(). setWidth(). warning(). 168 QPainter. setSelectionMode(). 152 QObject. setTop(). 168 QPen. x(). 101 QRadioButton. 167 QScrollView. setLeft(). setHeight(). 143 QObject. 168 QRect. 93 QObject. eraseRect(). 168 QRect. 124 QSpinBox. timerEvent(). 134 QRadioButton. 165. 149 QMessageBox. 168 QRect. 108 QListBox. 184 QListBox. 197 QSqlCursor. 102 QRect. select(). 143 QPainter.346 INDEKS QRect. 168 QRect. 225 QObject. 168 . 168 QPainter. sort(). setY(). value(). 109 QListBox. update().

setUsername(). 166 QTable. __init__(). 184 QSqlDatabase. 160. dengan Python. at(). clear(). 190 QSqlQuery. currentColumn(). 161. 184 QSqlDatabase. 160 QTable. 188. 197 QSqlQuery. prev(). horizontalHeader(). createEditor(). clearCell(). 192 QTable. activateNextCell(). 184 QSqlDatabase. 156 QTable. next(). 111 Qt. 173 347 QString. 210 QTable. 190 QSqlQuery. execQuery(). 155. value(). eld(). nd(). isEmpty(). addDatabase(). 90 QString. 161 QTable. 81 Qt. 190 QSqlQuery. 190 QSqlQuery. paintCell(). 166 QTable. 210 QTable. setHostName(). 191 QSqlQuery. 165 QTable. 190 QSqlQuery. beginEdit(). lastError(). 189 QSqlQuery. removeRow(). 184 QSqlError. modul. 166 QTable. databaseText(). 157 QTable. ISODate. 184 QSqlDatabase. 160 QTable. setCellContentFromEditor(). 184 QSqlError. 166 QTable. setPassword().INDEKS QSqlDatabase. currentRow(). insertRows(). resizeData(). 160. 225 qt. 190 QSqlQuery. 197 QSqlRecord. 184 QSqlDatabase. last(). 161. 166 QTable. seek(). 189 QSqlRecord. 93 Qt. rst(). 166. currentChanged(). 189. 166 . 191 QSqlRecord. 161 QTable. setDatabaseName(). 184 QSqlField. 90 QTable. cellWidget(). 197 QString. buer QSqlCursor.

modul. 157 QTable. 190 QVariant. text(). 190 QVBoxLayout. 156. setMinimumHeight(). 111 QWidget. 139 QTime. 117 QWidget. 139 QTime. setNumRows(). 166 QTabWidget. 104 radiobutton. setHide(). secsTo(). 179 qttable. 84. 131. 166 QTable. 161 QTable. 93 QWidget. 139 QTime. showMaximized(). 88 173 QTable. insertTab(). 129 QTextEdit. setText(). le. 139 QTime. addSecs(). 123. QRadioButton. 87. 139 QTime. font(). msec(). 190 QVariant. keyPressEvent(). modul. toDateTime(). 84 QWidget. updateCell(). show(). second(). 152 QWidget. 190 . 155 query. 97 QWidget. random. 189. 123 QWidget. 51 read. 160 QTable. pedoman. toDouble(). focusOutEvent(). 134 QWidget. 156. 157 QTable.348 INDEKS QVariant. 61 range(). closeEvent(). 134 QWidget. toString(). 132. QLabel. 99 radiobutton. hour(). setCurrentCell(). setColumnWidth(). 89. QTable. 139 QTime. 83. 127 QTabWidget. 185 QVariant. warna. modul. minute(). currentTime(). toInt(). 139 QTime. 111. 224 QWidget. 179. 190 QVariant. 139 qtsql. 60 raw_input(). setNumCols(). 88. 101 random(). setFocus(). toString(). 69 read-only. 131 QTime. 134 QWidget. 61 random. 139 QTime. setEnabled(). 157 QTable.

102 reset. istilah. QWidget. 102 selected(). 47 red. superuser MySQL. 90 select(). modul os. QButtonGroup. QSqlCursor. 127 removeItem(). QLayout. 98 setBottom(). status printer. list. 65. QTime. QRect. QListBox. 168 setBuddy(). 160. 24 scrolling. 76 ready. SQL. string. 115 reverse(). QFont. QDialog. 145 return. QComboBox. 23. Red Green Blue. 40 runtime. QScrollView. 185 selected(). 88 resizeData(). QTime.INDEKS read-only. 160 reject(). 75. 114 . 70 349 root. 85 setAutoAdd(). 180 round(). QTable. QButtonGroup. 98 setBold(). 139 ribuan. QRadioButton. 30 reset. 110 readlines(). 115 reset. 64 Return. 162 script. arti. 94. QComboBox. 106 setAutoResize(). 40 rjust(). 106 second(). QListBox. QSqlQuery. 166 rename(). 101 resize(). 78 root. 99 ribu(). 47 RGB. 98 reimplementation. superuser Linux. QDialog. 191 SELECT. 70 record. 108 removeRow(). 190 segmentation fault. 104 secsTo(). 93 repaintContents(). 108 self. QListBox. 69. 189 removeItem(). 139 seek(). keyboard. QDateTime. 167 reserved word pada text editor. 165 result(). 132 setAutoCompletion(). 145 rekursif. QLabel. 118 root. QLabel. 76 seek(). QTable. 143 secsTo(). le. list dua dimensi.

193 setStyle(). setCaption(). 167 setColumnWidth(). 184 setDefault(). 85 setCellContentFromEditor(). QLayout. 137 setSqlCursor(). 184 setPen(). QTable. 89 setText(). QApplication. QTable. 93 setFont(). 132. QFont. 99 setPassword(). QLayout. QBrush. QWidget. QRect. 97 setRight(). QTable. 167 setColor(). 109 setSpacing(). QComboBox. QRect. QSqlDatabase. QWidget. QRadioButton. QFont. QRect. 88 setHeight(). QPushButton. 97 setFocus(). QPen. 136 setEditable(). 156. 168 setPointSize(). QFont. 168 setHide(). 137 setMinimumHeight(). QWidget. QWidget. 111 setFamily(). 106 setEnabled(). 168 setSelectionMode(). QWidget. 156 setLeft(). 157 104 setButton(). QWidget. QTable. 145 setDirection(). QSqlDatabase. 156. 168 setMainWidget(). QBoxLayout. 166 setChecked(). 161 setDatabaseName(). 99 setPaletteForegroundColor(). 166 setNumRows(). 157 setHostName(). QListBox. QPainter. QDataTable. 98 setLabel(). QButtonGroup. 173 setCurrentCell(). QTable. 102 setColor().350 INDEKS setItalic(). QSqlDatabase. 184 . QWidget. QBrush. QTable. QHeader. 167 setText(). QTable. 134 setNumCols(). 97 setGeometry(). 83 setMargin(). 160 setPaletteBackgroundColor().

QSpinBox. QString menjadi string. 168 shape. 42 str(). 60 TableFile. QKeyEvent. 168 setY(). QListBox. 47 sort(). 170 tanggal(). 118 Sybase. 100 sistem KTP. 71. pemenggalan list. QRect. list dua dimensi. 18 sinyal. 185 startTimer(). 108 spinbox. 126 setValue(). qt. QFont. QWidget. 134 showmodal. 141 . 146 SIGNAL(). 168 sheet. 226 superuser database. 91. 61 strip(). QRect. 168 setUnderline(). 22 Shift. QSqlDatabase. 143 state(). 117 storage. keyboard. 91 string. os. 78 su. bidang gambar. 126 setWidth(). QRect. 45 slot. class. 161 SQL. QObject. 124 tabel. 93 siklus pengembangan. SQL. 199 Tanggal. 93 tabel. 76 splitelds(). modul.INDEKS setTop(). 184 setValue(). 180 superuser sistem operasi. 155 shell tools. 100 sistem operasi. 84 showMaximized(). 168 setX(). list. 98 setUsername(). 78 351 spreadsheet. QDial. 155 tabel. string ke QTime. 70 SUM(). 73 sys. 18. 72 system(). QRect. 76. 24 str(). 93 sort(). modul. QWidget. string. 179 syntax error. 155. 94 sistem kepegawaian. 47. string. le menjadi tabel. 21 slice. 72. 117 show(). dari le. 27 situs.

QCheckBox. QDateTime. SQL. 180 text editor. 21 update(). dictionary. 142 time. pengolahan. 185 variabel. 99 toInt(). 76 teks. 225 . 49 values. le teks. 117 value(). 89 text(). 76 TEXT. 96 UNIQUE. 29 text(). SQL. 95 template1. 140 Tcl. modul. 93 true. 157 text. 106 text(). QDate. 22 teksBerubah. 190 toString(). 55. QDate. 166 user. QObject. 95. QKeyEvent. 76 teks. modus teks. QVariant. LineCase. 185 updateCell(). 224 values(). 74 type(). QSqlCursor. QVariant. 48 VARCHAR.352 INDEKS toString(). 50 ukuran huruf. 210 Unix. 65 variant. 190 touch. QTable. QTable. 37 variabel. 189 valueChanged(). 197 UPDATE. QVariant. 190 toggle. QSqlQuery. QLineEdit. font. 98. QVariant. 190 toDouble(). 143 toDateTime(). 139 toString(). QTime. 88 value(). 22 teks. 121. QVariant. 71 underline. QSqlCursor. event LineCase. QLCDNumber. SQL. dictionary. QDateTime. QSpinBox. 143 timerEvent(). 61 timer. 141 toString(). 96 teksBerubah. QComboBox. 55. info tipe data. dictionary. CSV. 56 try. SQL. 117 text(). milik fungsi. 49 update(). 126 ValueGrid. class. 190 tanggal. 192 value(). 52. 111 time(). 161. 185 textChanged().

121 write. QDate. le. class. string ke QDateTime.INDEKS vi. 87 wadah. QRect. QMessageBox. 98 warning(). string. 186 visual object. 152 while. QRect. 199 WaktuDigital. 98 widget. 168 window manager. 140 yellow. 143. 168 year(). 29 virtual. 69 x(). 219 warna. 73. 60. 85 white. QColor. istilah. 73 zll(). 168 y(). 87 width(). 123 waktu(). 81 Windows. QRect. 98 ZeroDivisionError. le. 76 353 . 21 write().

Sign up to vote on this title
UsefulNot useful