Termasuk hal yang penting dalam pemrograman berbasis GUI adalah managemen layout. Managemen layout adalah suatu teknik atau cara bagaimana kita meletakkan widget-widget di atas window. Managemen layout tersebut bisa dilakukan dengan dua cara: dengan absolute positioning atau layout classes[1].

Absolute Positioning

Yaitu dengan cara kita mendefinisikan widget-widget dengan koordinat-koordinat absolute secara manual. Kita bisa menempatkan tombol di koordinat tertentu, lalu menempatkan widget lain di koordinat yang lain.

Akan tetapi, dengan absolute positioning, ada beberapa kekurangan yang harus kita ketahui terlebih dahulu [2].

  1. Ukuran dan posisi dari widget tidak akan berpindah dan berubah apa bila ukuran window berubah.
  2. Penampilan aplikasi kemungkinan besar akan berbeda di platform yang berbeda.
  3. Jika kita mengganti font, itu bisa merusak/mengganggu kesuluruhan penampilan layout.
  4. Jika kita berkeinginan untuk mengubah tampilan layout, maka kita perlu mengubah satu-persatu widget yang ada pada layout. Dan ini akan menghabiskan waktu serta tenaga yang banyak.

Contoh absolute layout

Buat window sederhana dulu dengan ukuran 300x200.

window = QtGui.QWidget()
window.resize(300, 200)
window.setWindowTitle('Tutorial PySide')

Tambahkan satu tombol. Tombol ini akan ditempatkan di posisi atas.

btn1 = QtGui.QPushButton('Tombol 1', window)
btn1.resize(280, 70)
btn1.move(10, 10)

Tambahkan satu tombol lagi, dan ditaruh di posisi sebagai mana kode berikut:

btn2 = QtGui.QPushButton('Tombol 2', window)
btn2.resize(135, 100)
btn2.move(10, 90)

Dan tombol terakhir, di posisi sebelah kanan tombol di atas.

btn3 = QtGui.QPushButton('Tombol 3', window)
btn3.resize(135, 100)
btn3.move(155, 90)

Lalu tampilkan window.

window.show()

Begini lah hasilnya.

Screenshot from 2017-09-29 21-07-30.png

Kita bisa mencoba untuk memperbesar ukuran window dengan mouse, dan kita akan mendapati tiga tombol di atas tetap pada posisinya yang semula, tidak menyesuaikan dengan keadaan window yang baru.

Screenshot from 2017-09-29 21-11-12.png

Layout Classes

Dengan menggunakan kelas layout, memanajemen layout pada window jadi lebih mudah dan praktis. Ini adalah cara yang direkomendasikan. Management layout pada PySide yang paling dasar adalah dengan menggunakan kelas PySide.QtGui.QHBoxLayout dan QtGui.QVBoxLayout. Keduanya menata widget secara horizontal dan vertikal di window. [3]

Semua kelas yang bertugas memanajemen layout pada PySide, adalah kelas turunan dari PySide.QtGui.QLayout. Kelas-kelas tersebut adalah: PySide.QtGui.QBoxLayout ,PySide.QtGui.QGridLayout ,PySide.QtGui.QFormLayout, dan PySide.QtGui.QStackedLayout .

Box Layout

Kelas Pyside.QtGui.QBoxLayout menempatkan widget-widget pada window secara horizontal atau secara vertikal [4]. Ia mengambil ruang kosong dari parent layout, lalu membagi-baginya menjadi kotak-kotak, dan tiap kotak-kotak tersebut akan diisi oleh widget.

Kita bisa membuat box layout dengan kode berikut.

layout = QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom, window)

Parameter pertama adalah direction. Yaitu bagaimana box layout akan menampilkan widget, apakah dari atas ke bawah? Dari bawah ke atas, dari kiri ke kanan atau sebaliknya? Kita bisa mendefinisikannya dengan konstan berikut:

Konstan Deskripsi
QBoxLayout.LeftToRight Horizontal dari kiri ke kanan
QBoxLayout.RightToLeft Horizontal dari kanan ke kiri
QBoxLayout.TopToBottom Vertikal dari atas ke bawah
QBoxLayout.BottomToTop Horizontal dari bawah ke atas

Buat 3 tombol seperti pada kode program sebelumnya.

btn1 = QtGui.QPushButton('Tombol 1')
btn2 = QtGui.QPushButton('Tombol 2')
btn3 = QtGui.QPushButton('Tombol 3')

Tambahkan ketiga tombol di atas ke dalam layout.

layout.addWidget(btn1)
layout.addWidget(btn2)
layout.addWidget(btn3)

Tampilkan window.

window.show()

Maka beginilah hasilnya:

Screenshot from 2017-10-01 16-10-48.png

Grid Layout

Kelas PySide.QtGui.QGridLayout menyusun dan mengatur widget dalam bentuk grid [5]. Ia mengambil ruang kosong dari parent layout, lalu membagi-baginya menjadi baris dan kolom, serta menempatkan widget-widget ke kolom yang tepat.

Kita bisa membuat grid layout dengan kode berikut.

layout = QtGui.QGridLayout(window)

Buat 4 tombol.

btn1 = QtGui.QPushButton('Tombol 1')
btn2 = QtGui.QPushButton('Tombol 2')
btn3 = QtGui.QPushButton('Tombol 3')
btn4 = QtGui.QPushButton('Tombol 4')

Lalu tambahkan tiap tombol dengan koordinat cell-nya. Ini terserah kita mau di tempatkan di mana tombol-tombol tersebut.

layout.addWidget(btn1, 0, 0)
layout.addWidget(btn2, 0, 1)
layout.addWidget(btn3, 1, 0)
layout.addWidget(btn4, 1, 1)

Dan ketika fungsi window.show dipanggil, penampakan aplikasinya akan terlihat seperti berikut:

Screenshot from 2017-10-01 16-28-25.png

Form Layout

Kelas PySide.QtGui.QFormLayout memanajemen widget-widget yang berhubungan dengan input form, dan label-label yang berasosiasi dengannya [6]. Dengan menggunakan kelas ini, layout akan dibagi menjadi dua bagian. Kiri dan kanan. Kiri untuk mengisi label dari input, sedangkan kolom kanan berisi inputan-nya.

Secara tradisional, kita bisa melakukan hal ini dengan menggunakan QGridLayout. Akan tetapi, jika kebutuhannya hanya untuk form, maka kodingan yang perlu kita tulis menjadi lebih sederhana dengan QFormLayout.

Contoh program. Buat instans dari kelas PySide.QtGui.QFormLayout.

layout = QtGui.QFormLayout(window)

Buat 3 buah line edit, dan satu buah tombol.

namaLineEdit = QtGui.QLineEdit()
emailLineEdit = QtGui.QLineEdit()
asalLineEdit = QtGui.QLineEdit()
submitBtn = QtGui.QPushButton('Submit')

Tambahkan masing-masing elemen di atas ke dalam layout.

layout.addRow('Nama', namaLineEdit)
layout.addRow('Email', emailLineEdit)
layout.addRow('Asal', asalLineEdit)
layout.addRow(submitBtn)

NB:
Di dalam instance layout, kita bisa memanggil fungsi addRow dengan dua cara. Yang pertama dengan dua parameter, yaitu parameter pertama adalah string, dan yang kedua adalah turunan dari kelas QtGui.QWidget. Seperti ketika kita menambahkan namaLineEdit beserta labelnya. Ada pun cara yang kedua, kita hanya memasukkan satu parameter saja, yaitu instance dari turunan kelas QtGui.QWidget, ini akan menambahkan widget di posisi paling bawah dengan lebar dua kolom memenuhi ukuran parent-nya. Seperti saat kita menambahkan submitBtn.

Berikut hasil dari program:

Screenshot from 2017-10-01 20-35-01.png

Kode Program Kesuluruhan

Versi Prosedural

Absolute Positioning

import sys
from PySide import QtGui

"""
Jago Ngoding tutorial PySide bahasa Indonesia

author: Ibnu Jakaria
"""

app = QtGui.QApplication(sys.argv)

window = QtGui.QWidget()
window.resize(300, 200)
window.setWindowTitle('Tutorial PySide')

btn1 = QtGui.QPushButton('Tombol 1', window)
btn1.resize(280, 70)
btn1.move(10, 10)

btn2 = QtGui.QPushButton('Tombol 2', window)
btn2.resize(135, 100)
btn2.move(10, 90)

btn3 = QtGui.QPushButton('Tombol 3', window)
btn3.resize(135, 100)
btn3.move(155, 90)

window.show()

sys.exit(app.exec_())

Box Layout

import sys
from PySide import QtGui

"""
Jago Ngoding tutorial PySide bahasa Indonesia

author: Ibnu Jakaria
"""

app = QtGui.QApplication(sys.argv)

window = QtGui.QWidget()
window.resize(300, 200)
window.setWindowTitle('Tutorial PySide')

layout = QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom, window)

btn1 = QtGui.QPushButton('Tombol 1')
btn2 = QtGui.QPushButton('Tombol 2')
btn3 = QtGui.QPushButton('Tombol 3')

layout.addWidget(btn1)
layout.addWidget(btn2)
layout.addWidget(btn3)

window.show()

sys.exit(app.exec_())

Grid Layout

import sys
from PySide import QtGui

"""
Jago Ngoding tutorial PySide bahasa Indonesia

author: Ibnu Jakaria
"""

app = QtGui.QApplication(sys.argv)

window = QtGui.QWidget()
window.resize(300, 200)
window.setWindowTitle('Tutorial PySide')

layout = QtGui.QGridLayout(window)

btn1 = QtGui.QPushButton('Tombol 1')
btn2 = QtGui.QPushButton('Tombol 2')
btn3 = QtGui.QPushButton('Tombol 3')
btn4 = QtGui.QPushButton('Tombol 4')

layout.addWidget(btn1, 0, 0)
layout.addWidget(btn2, 0, 1)
layout.addWidget(btn3, 1, 0)
layout.addWidget(btn4, 1, 1)

window.show()

sys.exit(app.exec_())

Form Layout

import sys
from PySide import QtGui

"""
Jago Ngoding tutorial PySide bahasa Indonesia

author: Ibnu Jakaria
"""

app = QtGui.QApplication(sys.argv)

window = QtGui.QWidget()
window.resize(300, 200)
window.setWindowTitle('Tutorial PySide')

layout = QtGui.QFormLayout(window)

namaLineEdit = QtGui.QLineEdit()
emailLineEdit = QtGui.QLineEdit()
asalLineEdit = QtGui.QLineEdit()
submitBtn = QtGui.QPushButton('Submit')

layout.addRow('Nama', namaLineEdit)
layout.addRow('Email', emailLineEdit)
layout.addRow('Asal', asalLineEdit)
layout.addRow(submitBtn)

window.show()

sys.exit(app.exec_())

Versi OOP

Absolute Positioning

import sys
from PySide import QtGui

"""
Jago Ngoding tutorial PySide berbahasa Indonesia

author: Ibnu Jakaria
"""

class Jendela(QtGui.QWidget):

  def __init__(self):
    super(Jendela, self).__init__()

    self.siapkanUI()

  def siapkanUI(self):
    self.resize(300, 200)
    self.setWindowTitle('Tutorial PySide')

    self.btn1 = QtGui.QPushButton('Tombol 1', self)
    self.btn1.resize(280, 70)
    self.btn1.move(10, 10)

    self.btn2 = QtGui.QPushButton('Tombol 2', self)
    self.btn2.resize(135, 100)
    self.btn2.move(10, 90)

    self.btn3 = QtGui.QPushButton('Tombol 3', self)
    self.btn3.resize(135, 100)
    self.btn3.move(155, 90)

app = QtGui.QApplication(sys.argv)
jendela = Jendela()
jendela.show()
sys.exit(app.exec_())

Box Layout

import sys
from PySide import QtGui

"""
Jago Ngoding tutorial PySide berbahasa Indonesia

author: Ibnu Jakaria
"""

class Jendela(QtGui.QWidget):

  def __init__(self):
    super(Jendela, self).__init__()

    self.siapkanUI()

  def siapkanUI(self):
    self.resize(300, 200)
    self.setWindowTitle('Tutorial PySide')

    self.btn1 = QtGui.QPushButton('Tombol 1')
    self.btn2 = QtGui.QPushButton('Tombol 2')
    self.btn3 = QtGui.QPushButton('Tombol 3')

    self.layout = QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom, self)
    self.layout.addWidget(self.btn1)
    self.layout.addWidget(self.btn2)
    self.layout.addWidget(self.btn3)

app = QtGui.QApplication(sys.argv)
jendela = Jendela()
jendela.show()
sys.exit(app.exec_())

Grid Layout

import sys
from PySide import QtGui

"""
Jago Ngoding tutorial PySide berbahasa Indonesia

author: Ibnu Jakaria
"""

class Jendela(QtGui.QWidget):

  def __init__(self):
    super(Jendela, self).__init__()

    self.siapkanUI()

  def siapkanUI(self):
    self.resize(300, 200)
    self.setWindowTitle('Tutorial PySide')

    self.btn1 = QtGui.QPushButton('Tombol 1')
    self.btn2 = QtGui.QPushButton('Tombol 2')
    self.btn3 = QtGui.QPushButton('Tombol 3')
    self.btn4 = QtGui.QPushButton('Tombol 4')

    self.layout = QtGui.QGridLayout(self)
    self.layout.addWidget(self.btn1, 0, 0)
    self.layout.addWidget(self.btn2, 0, 1)
    self.layout.addWidget(self.btn3, 1, 0)
    self.layout.addWidget(self.btn4, 1, 1)

app = QtGui.QApplication(sys.argv)
jendela = Jendela()
jendela.show()
sys.exit(app.exec_())

Form Layout

import sys
from PySide import QtGui

"""
Jago Ngoding tutorial PySide berbahasa Indonesia

author: Ibnu Jakaria
"""

class Jendela(QtGui.QWidget):

  def __init__(self):
    super(Jendela, self).__init__()

    self.siapkanUI()

  def siapkanUI(self):
    self.resize(300, 200)
    self.setWindowTitle('Tutorial PySide')

    self.namaLineEdit = QtGui.QLineEdit()
    self.emailLineEdit = QtGui.QLineEdit()
    self.asalLineEdit = QtGui.QLineEdit()
    self.submitBtn = QtGui.QPushButton('Submit')

    self.layout = QtGui.QFormLayout(self)
    self.layout.addRow('Nama', self.namaLineEdit)
    self.layout.addRow('Email', self.emailLineEdit)
    self.layout.addRow('Asal', self.asalLineEdit)
    self.layout.addRow(self.submitBtn)

app = QtGui.QApplication(sys.argv)
jendela = Jendela()
jendela.show()
sys.exit(app.exec_())

Catatan Kaki:
[1] Jan Bodnar, "Layout management in PySide", ZetCode, zetcode.com/gui/pysidetutorial/layoutmanagement/, diakses tanggal 29 September 2017
[2] Ibid.
[3] Ibid.
[4] "QBoxLayout", PySide v1.07 documentation, https://srinikom.github.io/pyside-docs/PySide/QtGui/QBoxLayout.html, diakses tanggal 01 Oktober 2017
[5] "QGridLayout", PySide v1.07 documentation, https://srinikom.github.io/pyside-docs/PySide/QtGui/QGridLayout.html, diakses tanggal 01 Oktober 2017
[6] "QFormLayout", PySide v1.07 documentation, https://srinikom.github.io/pyside-docs/PySide/QtGui/QFormLayout.html