#JuliNgeblog Der zweite Tag : Delegate Mouse Event Signal on QLabel

Selamat datang kembali!

Tulisan hari kedua sudah mulai masuk ke topik yang teknis. Persoalannya adalah ketika mau menangkap sinyal tetikus (press, release, move) untuk menggambar. Ketika menggunakan delphi dulu, prosedur untuk menangani event tetikus bisa dibuat terpisah dari komponen yang menjadi tempat terjadinya event. Misalnya, ketika ada event mouse di atas komponen Image, maka prosedur penanganannya bisa dibuat sebagai method dari objek Form. Salah satu contoh skenarionya adalah ketika terjadi sesuatu di komponen ini, maka akan disimpan perintah menggambar dan proses penggambaran di komponen yang bisa menggambar bisa didekorasi dengan penunjuk objek apa yang akan digambar tanpa mengganggu kondisi yang sudah ada (misal. rubberband).

dip

Masalah muncul ketika mau menerapkan cara serupa pada konteks Qt di python (PyQt atau PySide). Pada konteks ini, kelas yang memiliki buffer untuk menggambar ada di QImage. Agar gambar di objek ini dapat ditampilkan, Objek QImage perlu dipasang di Objek QLabel. Penanganan event mouse dilakukan di QLabel. Pendekatan untuk menangani proses semacam ini adalah dengan membuat kelas turunan QLabel atau QWidget untuk kebutuhan yang berbeda yang tentu saja merepotkan. Saya perlu satu komponen kecil yang bisa dipakai untuk beberapa konteks penggambaran yang berbeda tapi memiliki mekanisme yang sama (prosedur penanganan ada di objek lain).

Setelah membaca manual, ternyata membuat sinyal event cukup mudah:

  1. deklarasikan objek sinyal internal
  2. lempar sinyal sesuai dengan keadaan yang diinginkan (dalam hal ini, setiap terjadi mouse event)

Penjelasan lebih lanjut dapat dilihat di kode berikut :

class QMLabel(QtGui.QLabel):
	mousePressed = QtCore.Signal(QtGui.QMouseEvent)
	mouseMove = QtCore.Signal(QtGui.QMouseEvent)
	mouseReleased = QtCore.Signal(QtGui.QMouseEvent)

	def __init__(self, parent):
		super(QMLabel, self).__init__(parent)
		self.setMouseTracking(True)

	def mousePressEvent(self, event):
		self.mousePressed.emit(event)
		super(QMLabel, self).mousePressEvent(event)

	def mouseMoveEvent(self, event):
		self.mouseMove.emit(event)
		super(QMLabel, self).mouseMoveEvent(event)

	def mouseReleaseEvent(self, event):
		self.mouseReleased.emit(event)
		super(QMLabel, self).mouseReleaseEvent(event)

Di kode tersebut, saya membuat tiga event yang akan dilempar (didelegasikan). Pada setiap kode penangan event, saya lempar sinyal internal (prosedur emit).

Cara menggunakan kelas ini sama seperti ketika menggunakan komponen lain. rinciannya bisa dilihat di kode berikut :

class PickWidget(QtGui.QWidget):
	postAction = QtCore.Signal()
	def __init__(self, parent):
		super(PickWidget, self).__init__(parent)

		#offline buffer
		self.trackimage = QtGui.QImage(660, height, QtGui.QImage.Format_RGB32)

		self.tracklabel = QMLabel(self)
		self.tracklabel.setPixmap(QtGui.QPixmap.fromImage(self.trackimage))
		self.tracklabel.adjustSize()

		self.tracklabel.mousePressed.connect(self.mousepress)
		self.tracklabel.mouseReleased.connect(self.mouserelease)
		self.tracklabel.mouseMove.connect(self.mousemove)

	def mousepress(self, event):
		pass

	def mouserelease(self, event):
		pass

	def mousemove(self, event):
		pass

Sekian dulu catatan kali ini. Mudah-mudahan bermanfaat bagi saya sendiri kalau sewaktu-waktu lupa atau untuk anda kalau bertemu dengan persoalan yang sama.

Wassalam,

Iklan

Introducing PEBCLIPS

Pengalaman pertama saya menggunakan CLIPS [1] adalah ketika saya mengambil mata kuliah sistem berbasis pengetahuan sewaktu S1. Waktu itu saya membuat tugas besar dengan topik sistem untuk penyusun playlist lagu otomatis (sistem pakar music director radio siaran atau ESMooD ~ Expert System for Music Director) yang pakarnya merupakan teman-teman kru di Radio Kampus ITB yang memang pekerjaan hariannya menyusun playlist lagu untuk keperluan siaran.

CLIPS yang saya ketahui waktu itu antarmuka dengan penggunanya kalau tidak berbasis console (CLIPS.exe) atau WebCLIPS sedangkan aplikasi sistem pakar yang ingin saya buat adalah program berbasis desktop GUI supaya bisa langsung digunakan (:D). Akhirnya saya menemukan komponen VCL yang membungkus CLIPS.dll sehingga bisa digunakan dalam lingkungan Delphi (:victory:). Karena keterbatasan waktu pengerjaan tugas dan pengetahuan waktu itu, programnya pun dibuat ala kadarnya saja. Mekanisme yang digunakan di dalamnya hanya melakukan load basis kaidah, fakta awal yang merupakan preference dari seorang music director (MD) dan daftar lagu yang dianggarkan untuk minggu tertentu, lalu menjalankan mesin inferensi tanpa proses interaksi dan hasil playlist didapat dari melakukan dump working memory.

Beberapa waktu (lebih tepatnya bulan) yang lalu saya mengembangkan aplikasi Desktop GUI sebagai perantara antarmuka untuk CLIPS menggunakan delphi. Aplikasi ini cara kerjanya mirip dengen WEBCLIPS hanya saja untuk mengaksesnya langsung pada desktop. Fasilitas yang sudah tercapai antara lain MessageBox ,Status Message, dan Multi text untuk menampilkan teks, Radio Group, Checkbox, dan InputBox untuk mendapatkan masukan, Fasilitas untuk menyimpan dan membuka session, serta menampilkan daftar fakta dalam bentuk pohon. Kode dan binary sudah saya simpan di Google tapi dokumentasinya belum ada dan contoh aplikasinya juga (sebetulnya sudah ada aplikasi yang menggunakan pebclips, namun aplikasi itu milik orang lain dan mungkin diniatkan menjadi produk komersil sehingga tidak bisa disertakan). Semoga saja aplikasi ini bisa bermanfaat dan bisa terus dikembangkan. 😀

tampilan pebclips

tampilan pebclips