Apliksi Pembuka Foto PySide versi 9

BelajarPython - Assalamualaikum wr. wb.

Jumpa lagi temen - temen... Kali ini, saya akan mengajak kalian untuk membuat sebuah pembuka foto nih.. Dengan tampilan yang cukup bagus.. Karena menggunakan library PySide. Penasaran ? Langsung saja yuk kita simak sama - sama...

Pengenalan aplikasi yang akan kita buat.

Sebenarnya, saya sudah membuat aplkasi pembuka foto juga.. Namun menggunakan library Tkinter.. jadi, tampilannya tidak terlalu menarik dan terlihat jadul (KLIK DISINI untuk melihatnya).. Namun pada projek ini, saya menggunakan PySide untuk mendapatkan fungsi dan tampilan yang lebih baik..

Namun, Aplikasi ini saya posting dengan berbagai versi.. Dengan penambahan fitur di tiap versinya.. Jika kalian ingin melihat versi - versi aplikasi ini, KALIAN BISA KLIK DISINI ya temen - temen...

Dan Sekarang, saya akan memberikan versi 9 nya. Dimana pada versi ini saya akan menambahkan fitur menyesuaikan ukuran gambar agar termuat seluruhnya pada window. Sederhana tapi akan sangat mempengaruhi kenyamanan saat melihat foto.

Rincian Lengkap Aplikasi Pembuka Foto PySide Versi 9.0

Aplikasi kali ini menggunakan library PySide. Jadi, untuk menjalankannya, harus install dulu... KLIK DISINI untuk menginstallnya.... Dan berikut rincian lengkap aplikasinya...

Nama: mn-FotoView 9.0
Versi: 9.0 | klik disini untuk membaca versi pertama/awal.
Platform: Python 3.x
Modul: PySide. Klik disini untuk menginstallnya.
Baris Code: kurang lebih 339 baris code program.
Terdiri dari: 1 class dan 24 metode.
Fitur: Menyesuaikan ukuran (resolusi) gambar dengan window.
Kelemahan: sering tidak pas saat menyesuaikan ukuran gambar.
syarat menjalankan: install python 3.x dan PySide, punya editor teks atau IDE.
Cara menjalankan: install python 3 dan PySide, copy dan paste code program pada editor atau IDE, simpan dalam file python(ekstensi .py), lalu jalankan.

Kalian juga bisa membuat code program ini menjadi file aplikasi loh.. iya file aplikasi seperti "exe" itu.. sehingga, nantinya kita cukup klik dua kali saja untuk menjalankan aplikasi ini... tanpa perlu repot - repot membuka nya di IDLE atau IDE python.. nah seperti apa caranya? cukup mudah kok.. dan saya juga sudah membuatkan tutorialnya.. untuk kalian yang menggunakan windows, KALIAN BISA KLIK DISINI ya temen - temen.. atau jika pada link pertama terlalu rumit, KALIAN BISA MENCOBA CARA INI ya.... dan bagi pengguna linux ? tenang saja.. bisa juga kok membuat file executable nya.. untuk melihat tutorialnya, KALIAN BISA KLIK DISINI temen - temen...

Code program aplikasi Pembuka Foto PySide versi 9.0

Nah lalu seperti apa code program dari aplikasi Pemutar Musik PySide pada versi kali ini ? Oke, Berikut saya berikan code program nya ya...


from PySide.QtGui import *
from PySide.QtCore import *
import sys,os

class PembukaFoto(QMainWindow):
    def __init__(self):
        super(PembukaFoto, self).__init__()

        self.ukuranGambar = 1.0
        self.penampungLokasi = []
        self.posisi = 0
        self.updateTimer = QTimer()

        self.layout()
        self.layar()
        self.setScroll()
        self.buatToolBar()

    def layout(self):
        widgetLayout=QWidget(self)
        self.mainLayout =QVBoxLayout(widgetLayout)
        self.mainLayout.setContentsMargins(0,0,0,0)
        self.mainLayout.setSpacing(0)
        self.setCentralWidget(widgetLayout)

    def layar(self):
        self.tempatFoto = QLabel(self)
        self.tempatFoto.setScaledContents(True)
        self.mainLayout.addWidget(self.tempatFoto)

    def setScroll(self):
        # mengatur scroll
        self.scrollArea = QScrollArea()
        self.scrollArea.setWidget(self.tempatFoto)
        self.scrollArea.setBackgroundRole(QPalette.Light)
        self.scrollArea.setAlignment(Qt.AlignCenter)

        self.mainLayout.addWidget(self.scrollArea)

    def bukaGambar(self, gambar):
        image = QImage(gambar)
        pp = QPixmap.fromImage(image)
        self.tempatFoto.setPixmap(pp.scaled(pp.size(), Qt.KeepAspectRatio))
        self.tempatFoto.adjustSize()
        self.ukuranGambar = 1.0
        self.setWindowTitle(os.path.basename(gambar)+' - mn-belajarpython.blogspot.co.id')
        self.sesuaikan()

    def sesuaikan(self):
        lebarFoto = self.tempatFoto.pixmap().size().width()
        tinggiFoto = self.tempatFoto.pixmap().size().height()
        lebarTempatFoto = self.scrollArea.size().width()
        tinggiTempatFoto = self.scrollArea.size().height()

        if tinggiFoto > tinggiTempatFoto and lebarFoto > lebarTempatFoto :
            margin = 5

            if tinggiFoto < lebarFoto:
                pengali = lebarTempatFoto / lebarFoto
                self.tempatFoto.resize(QSize((lebarTempatFoto) - margin, (tinggiFoto * pengali) - margin))
            else:
                pengali = tinggiTempatFoto / tinggiFoto
                self.tempatFoto.resize(QSize((lebarFoto)-margin * pengali, (tinggiTempatFoto)- margin))

    def buatToolBar(self):
        self.toolBar = QToolBar()

        self.tombolBuka = QAction(self.tr("Buka"), self)
        self.tombolIn = QAction(self.tr("In"), self)
        self.tombolOut = QAction(self.tr("Out"), self)
        self.tombolFull = QAction(self.tr("Full"), self)
        self.tombolFit = QAction(self.tr("Fit"), self,checkable=True)
        self.tombolNormal = QAction(self.tr("Normal"), self)
        self.tombolNext = QAction(self.tr("Next"), self)
        self.tombolPrevious = QAction(self.tr("Prev"), self)
        self.tombolShow = QAction(self.tr("Show"), self)
        self.tombolHapus = QAction(self.tr("Hapus"), self)
        self.tombolTentang = QAction(self.tr("Tentang"), self)
        self.tombolRincian = QAction(self.tr("Rincian"), self)

        self.tombolBuka.triggered.connect(self.buka)
        self.tombolIn.triggered.connect(self.perbesar)
        self.tombolOut.triggered.connect(self.perkecil)
        self.tombolNormal.triggered.connect(self.ukuranNormal)
        self.tombolFit.triggered.connect(self.pasJendela)
        self.tombolNormal.triggered.connect(self.ukuranNormal)
        self.tombolFull.triggered.connect(self.tampilanPenuh)
        self.tombolNext.triggered.connect(self.next)
        self.tombolPrevious.triggered.connect(self.previous)
        self.tombolShow.triggered.connect(self.slideShow)
        self.tombolHapus.triggered.connect(self.hapus)
        self.tombolTentang.triggered.connect(self.tentang)
        self.tombolRincian.triggered.connect(self.rincian)

        self.tombolIn.setEnabled(False)
        self.tombolOut.setEnabled(False)
        self.tombolNormal.setEnabled(False)
        self.tombolFit.setEnabled(False)
        self.tombolNormal.setEnabled(False)
        self.tombolFull.setEnabled(False)
        self.tombolNext.setEnabled(False)
        self.tombolPrevious.setEnabled(False)
        self.tombolShow.setEnabled(False)
        self.tombolHapus.setEnabled(False)
        self.tombolRincian.setEnabled(False)

        self.toolBar.addSeparator()
        self.toolBar.addAction(self.tombolBuka)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.tombolIn)
        self.toolBar.addAction(self.tombolOut)
        self.toolBar.addAction(self.tombolNormal)
        self.toolBar.addAction(self.tombolFit)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.tombolFull)
        self.toolBar.addAction(self.tombolShow)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.tombolNext)
        self.toolBar.addAction(self.tombolPrevious)
        self.toolBar.addAction(self.tombolHapus)
        self.toolBar.addAction(self.tombolRincian)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.tombolTentang)
        self.toolBar.addSeparator()


        self.layoutToolbar = QHBoxLayout()
        self.layoutToolbar.addStretch()
        self.layoutToolbar.addWidget(self.toolBar)
        self.layoutToolbar.addStretch()
        self.layoutToolbar.setContentsMargins(0,0,0,0)

        self.mainLayout.addLayout(self.layoutToolbar)

    def perbesar(self):
        self.ubahUkuran(1.25)
        if self.ukuranGambar != 1 :
            self.tombolNormal.setEnabled(True)
        else :
            self.tombolNormal.setEnabled(False)

    def perkecil(self):
        self.ubahUkuran(0.8)
        if self.ukuranGambar != 1 :
            self.tombolNormal.setEnabled(True)
        else :
            self.tombolNormal.setEnabled(False)

    def ukuranNormal(self):
        self.tempatFoto.adjustSize()
        self.sesuaikan()
        self.ukuranGambar = 1.0
        self.tombolNormal.setEnabled(False)

    def pasJendela(self):
        pasJendela = self.tombolFit.isChecked()
        self.scrollArea.setWidgetResizable(pasJendela)
        if not pasJendela:
            self.ukuranNormal()
            self.tombolFit.setText('Fit')
        else :
            self.tombolFit.setText('unFit')
        self.pengaktifTombol()
        self.sesuaikan()

    def ubahUkuran(self, factor):
        self.ukuranGambar *= factor
        self.tempatFoto.resize(self.ukuranGambar * self.tempatFoto.pixmap().size())
        self.tempatFoto.setAlignment(Qt.AlignRight)

    def pengaktifTombol(self):
        self.tombolIn.setEnabled(not self.tombolFit.isChecked())
        self.tombolOut.setEnabled(not self.tombolFit.isChecked())
        if self.ukuranGambar != 1 and self.tombolFit.isChecked() == False:
            self.tombolNormal.setEnabled(True)
        else :
            self.tombolNormal.setEnabled(False)
        self.tombolFull.setEnabled(not self.tombolFit.isChecked())

    def keyPressEvent(self, keyevent):
        event = keyevent.key()
        if event == Qt.Key_Escape:
            self.tampilanPenuh()
        if event == Qt.Key_A:
            self.previous()
        if event == Qt.Key_D:
            self.next()
        if event == Qt.Key_W:
            self.tampilanPenuh()

    def tampilanPenuh(self):
        if self.isFullScreen():
            self.showNormal()
            self.updateTimer.stop()
            self.toolBar.show()
            self.tombolFull.setText('Full')
        else:
            self.showFullScreen()
            self.tombolFull.setText('unFull')

    def next(self):
        if len(self.penampungLokasi) > 1 :
            if len(self.penampungLokasi)>self.posisi+1:
                self.posisi += 1
            else:
                self.posisi = 0
            self.bukaGambar(self.penampungLokasi[self.posisi])

    def previous(self):
        if len(self.penampungLokasi) > 1 :
            if 0 < self.posisi :
                self.posisi -= 1
            else:
                self.posisi = len(self.penampungLokasi)-1

            self.bukaGambar(self.penampungLokasi[self.posisi])

    def buka(self):
        fileName,_ = QFileDialog.getOpenFileName(self, "Pilih File Gambar", QDir.currentPath(), filter="JPG (*.jpg);;PNG (*.png);;All (*.*) ")

        if fileName:
            image = QImage(fileName)
            if image.isNull():
                QMessageBox.information(self, "Image Viewer",
                        "Maaf! tidak bisa membuka file --> %s." % os.path.basename(fileName))
                return

            self.bukaGambar(fileName)
            lokasi = [os.path.dirname(fileName)]
            self.lokasiGambar(lokasi)

            for i in range(len(self.penampungLokasi)) :
                if self.penampungLokasi[i] == fileName :
                    self.posisi = i
                    break

            if len(self.penampungLokasi) > 1 :
                self.tombolNext.setEnabled(True)
                self.tombolPrevious.setEnabled(True)
                self.tombolShow.setEnabled(True)
            else:
                self.tombolNext.setEnabled(False)
                self.tombolPrevious.setEnabled(False)
                self.tombolShow.setEnabled(False)

            self.tombolHapus.setEnabled(True)
            self.tombolFit.setEnabled(True)
            self.tombolRincian.setEnabled(True)
            self.pengaktifTombol()

    def fileValid(self, filename):
        if filename.endswith('PNG') or filename.endswith('png') or \
                filename.endswith('JPG') or filename.endswith('jpg'):
            return True

    def lokasiGambar(self, lokasi):
        self.penampungLokasi = []
        for gambar in lokasi:
            try:
                lokasiGambar = os.listdir(gambar)
            except OSError:
                raise OSError("Provided path '%s' doesn't exists." % gambar)

            for lokasinya in lokasiGambar:
                item = os.path.join(gambar, lokasinya)
                if os.path.isfile(item) and self.fileValid(item):
                    self.penampungLokasi.append(item)
        return list(set(self.penampungLokasi))

    def slideShow(self):
        self.connect(self.updateTimer, SIGNAL("timeout()"), self.next)
        self.showFullScreen()
        self.toolBar.hide()
        self.updateTimer.start(4000)

    def hapus(self):
        if len(self.penampungLokasi) > 0 :
            self.file = QFile(self.penampungLokasi[self.posisi])
            tombol1 = QMessageBox.StandardButton.Yes
            tombol2 = QMessageBox.StandardButton.No
            pertanyaan = "anda yakin ingin menghapus permanen gambar ini?"
            response = QMessageBox.question(self, "Question", pertanyaan, tombol1, tombol2)
            if response == QMessageBox.Yes:
                self.file.remove()
                self.penampungLokasi.pop(self.posisi)
                if len(self.penampungLokasi) > 0 :
                    self.next()
                    if len(self.penampungLokasi) == 1 :
                        self.tombolNext.setEnabled(False)
                        self.tombolPrevious.setEnabled(False)
                else :
                    self.tempatFoto.setPixmap(None)
                    self.tombolIn.setEnabled(False)
                    self.tombolOut.setEnabled(False)
                    self.tombolNormal.setEnabled(False)
                    self.tombolFit.setEnabled(False)
                    self.tombolFull.setEnabled(False)
                    self.tombolNext.setEnabled(False)
                    self.tombolPrevious.setEnabled(False)
                    self.tombolShow.setEnabled(False)
                    self.tombolHapus.setEnabled(False)
                    self.tombolRincian.setEnabled(False)
                    self.setWindowTitle('Photo Viewer - mn-belajarpython.blogspot.co.id')

    def tentang(self):
        QMessageBox.information(self, "Tentang aplikasi",
                self.tr("Aplikasi ini merupakan sebuah apliakasi sederhana. "
                        "Namun, saya rasa aplikasi ini sudah cukup bagus "
                        "dari segi design. karena, didukung oleh modul yang "
                        "cukup lengkap dari PySide. sehingga saya hanya "
                        "menggunakannya saja\n"
                        "\nShortcut Tombol :"
                        "\n- esc / W \t : keluar/masuk dari fullscreen.\n"
                        "- A \t : gambar sebelumnya.\n"
                        "- D \t : gambar selanjutnya.\n"
                        "\nnah gimana ? menarikkan ? yuk kunjungi :  "
                        "mn-belajarpython.blogspot.co.id untuk tutorial "
                        "menarik lainnya..."))

    def rincian(self):
        data = QFileInfo(self.penampungLokasi[self.posisi])
        QMessageBox.information(self, "Rincian", self.tr("Nama \t : "+str(data.baseName())+
                                                         "\nFormat \t : "+str(data.completeSuffix())+
                                                         "\nUkuran \t : "+str(data.size()/1000)+' Kb'+
                                                         "\nLokasi \t : "+str(data.path())+
                                                         "\nDibuat \t : "+str(data.created().toString('dddd, d MMMM yyyy || hh:mm:ss a'))+
                                                         "\nPemilik \t : "+str(data.owner())
                                                         ))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setQuitOnLastWindowClosed(True)
    window = PembukaFoto()
    window.show()
    window.setGeometry(0,0,700,500)
    window.setWindowTitle('Photo Viewer - mn-belajarpython.blogspot.co.id')

    screen = QDesktopWidget().screenGeometry()
    size = window.geometry()
    window.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)

    sys.exit(app.exec_())



Nah lalu, seperti apakah tampilan yang akan di hasilkan dari code program di atas? Langsung saja yuk kita simak sama - sama tampilannya di bawah ini...


Penjelasan code program Aplikasi Pembuka Foto PySide versi 8.0

Sekarang saya akan mencoba untuk menjelaskan code program yang sudah saya bagikan di atas tadi.. Agar kalian lebih mudah untuk memahaminya.. Oke, Langsung saja yuk kita simak sama penjelasannya di bawah ini....
[NOTE : Teks berwarna MERAH pada penjelasan adalah Code tambahan yang tidak ada di versi sebelumnyaDan yang Berwarna BIRU akan di hapus di versi berikutnya. Jika Code berwarna MERAH dan komentar berwarna BIRU maka merupakan code baru dan akan di hapus di versi berikutnya]

from PySide.QtGui import *  //mengimport class ‘QtGui’ dan turunannya
from PySide.QtCore import *  //mengimport class ‘QtCore’ dan turunannya
import sys,os  //import class sys dan os

class PembukaFoto(QMainWindow):  //membuat class ‘PembukaFoto’. Dengan menurunkan class ‘QmainWindow’
    def __init__(self):  //membuat construktor class ‘PembukaFoto’
        super(PembukaFoto, self).__init__()  //memanggil construktor dari parent class ‘PembukaFoto’

        self.ukuranGambar = 1.0  //digunakan untuk nilai ukuran gambar pertama kali
        self.penampungLokasi = []  //inisialisasi variabel untuk menampung semua foto yang ada di folder tempat file foto yang di pilih untuk di tampilkan
        self.posisi = 0  //digunakan untuk menentukan posisi foto
        self.updateTimer = QTimer()  //inisialisasi timer

        self.layout()  //menjalankan metode ‘layout’
        self.layar()  //menjalankan metode ‘layar’
        self.setScroll()  //menjalankan metode ‘setScroll’
        self.buatToolBar()  //menjalankan metode ‘buatToolBar’

    def layout(self):  //membuat metode ‘layout’
        widgetLayout=QWidget(self)  //Memanggil dan menampung class ‘Qwidget’
        self.mainLayout =QVBoxLayout(widgetLayout)  //membuat layout utama
        self.mainLayout.setContentsMargins(0,0,0,0)  //mengatur window agar tidak ada margin
        self.mainLayout.setSpacing(0)  //mengatur agar tidak ada jarak tiap elemen agar
        self.setCentralWidget(widgetLayout)  //memasukkan widget pada variabel ‘WidgetLayout’ untuk menjadi layout utama di window

    def layar(self):  //membuat metode ‘layar’
        self.tempatFoto = QLabel(self)  //membuat QLabel sebagai tempat menampilkan foto
        self.tempatFoto.setScaledContents(True)  //membuat ukuran label ‘tempatFoto’ agar mengikuti ukuran foto
        self.mainLayout.addWidget(self.tempatFoto)  //memasukkan Tempat foto ke dalam layout utama / window

    def setScroll(self):  //membuat metode ‘setScroll’
        # mengatur scroll
        self.scrollArea = QScrollArea()  //membuat area scroll
        self.scrollArea.setWidget(self.tempatFoto)  //memasukkan ‘tempatFoto’ sebagai area yang akan di beri scroll bar
        self.scrollArea.setBackgroundRole(QPalette.Light)  //memberikan warna background area scroll
        self.scrollArea.setAlignment(Qt.AlignCenter)  //membuat ‘tempatFoto’ berada di tengah area scrollbar

        self.mainLayout.addWidget(self.scrollArea)  //memasukkar area scrollbar ke main layout/window

    def bukaGambar(self, gambar):  //membuat metode ‘bukaGambar’ dengan 1 buah parameter
        image = QImage(gambar)  //memuat foto dengan memasukkan path yang ada di variabel ‘gambar’
        pp = QPixmap.fromImage(image)  //membuat pixmap
        self.tempatFoto.setPixmap(pp.scaled(pp.size(), Qt.KeepAspectRatio))  //memasukkan foto (pixmap) ke dalam label (tempatFoto)
        self.tempatFoto.adjustSize()  //mengatur ukuran tempat foto agar sesuai
        self.setWindowTitle(os.path.basename(gambar)+' - mn-belajarpython.blogspot.co.id')  //mengubah judul menjadi nama foto
        self.sesuaikan()  //menjalankan metode ‘sesuaikan’

    def sesuaikan(self):    //membuat metode ‘sesuaikan’
        lebarFoto = self.tempatFoto.pixmap().size().width()  //mendapatkan lebar foto
        tinggiFoto = self.tempatFoto.pixmap().size().height()  //mendapatkan tinggi foto
        lebarTempatFoto = self.scrollArea.size().width()  //mendapatkan lebar tempat foto
        tinggiTempatFoto = self.scrollArea.size().height()  //mendapatkan tinggi tempat foto
        
        if tinggiFoto > tinggiTempatFoto or lebarFoto > lebarTempatFoto :  //memastikan apakah tinggi dan lebar foto lebih besar dari tinggi dan lebar tempat foto (salah satu harus lebih besar)
            margin = 5  //menentukan margin sebesar 5

            if tinggiFoto < lebarFoto:  //mengecek apakah tinggi foto lebih besar dari lebar foto
                pengali = lebarTempatFoto / lebarFoto  //membagi lebarTempatFot dengan lebar foto
                self.tempatFoto.resize(QSize((lebarTempatFoto) - margin, (tinggiFoto * pengali) - margin))  //mengubah ukuran foto sesuai dengan tempat foto
            else:  //jika tinggi foto lebih kecil dari lebar foto
                pengali = tinggiTempatFoto / tinggiFoto  //membagi tinggiTempatFot dengan tinggi foto
                self.tempatFoto.resize(QSize((lebarFoto)-margin * pengali, (tinggiTempatFoto)- margin))  //mengubah ukuran foto sesuai dengan tempat foto

    def buatToolBar(self):  //membuat metode ‘buatToolBar’
        self.toolBar = QToolBar()  //inisialisasi toolbar

        self.tombolBuka = QAction(self.tr("Buka"), self)  //Membuat perintah ‘Buka’
        self.tombolIn = QAction(self.tr("In"), self)   //membuat perintah ‘In’ (Perbesar)
        self.tombolOut = QAction(self.tr("Out"), self)   //membuat perintah ‘Out’ (Perkecil)
        self.tombolFull = QAction(self.tr("Full"), self)  //membuat perintah ‘Full’ (Fullscreen aplikasi)
        self.tombolFit = QAction(self.tr("Fit"), self,checkable=True)  //membuat perintah ‘Fit’ (mengubah ukuran foto sama seperti ukuran aplikasi)
        self.tombolNormal = QAction(self.tr("Normal"), self)  //membuat perintah ‘Normal’ (menormalkan ukuran foto)
        self.tombolNext = QAction(self.tr("Next"), self)  //membuat perintah ‘Next’ (foto berikutnya)
        self.tombolPrevious = QAction(self.tr("Prev"), self)  //membuat perintah ‘Previous’ (foto sebelumnya)
        self.tombolShow = QAction(self.tr("Show"), self)  //membuat perintah ‘show’ (slide show)
        self.tombolHapus = QAction(self.tr("Hapus"), self)  //membuat perintah hapus (menghapus foto)
        self.tombolTentang = QAction(self.tr("Tentang"), self)  //membuat perintah ‘Tentang’ (tentang Aplikasi)
        self.tombolRincian = QAction(self.tr("Rincian"), self)  //membuat perintah ‘rincian’ (rincian foto)

        self.tombolBuka.triggered.connect(self.buka)  //menjalanakan metode ‘buka’ ketika perintah ‘Buka’ (Tombol Buka) di klik
        self.tombolIn.triggered.connect(self.perbesar)  //menjalanakan metode ‘perbesar’ ketika perintah ‘In’ (Tombol perbesar) di klik
        self.tombolOut.triggered.connect(self.perkecil)  //menjalanakan metode ‘perkecil’ ketika perintah ‘Out’ (Tombol Perkecil) di klik
        self.tombolNormal.triggered.connect(self.ukuranNormal)  //menjalanakan metode ‘ukuranNormal’ ketika perintah ‘Normal’ (Tombol Normall) di klik
        self.tombolFit.triggered.connect(self.pasJendela)  //menjalanakan metode ‘pasJendela’ ketika perintah ‘Fit’ (Tombol Fit) di klik
        self.tombolFull.triggered.connect(self.tampilanPenuh)  //menjalanakan metode ‘tampilanPenuh’ ketika perintah ‘Full’ (Tombol Full) di klik
        self.tombolNext.triggered.connect(self.next)  //menjalankan metode ‘next’ ketikan ‘tombolNext’ di klik
        self.tombolPrevious.triggered.connect(self.previous)  //menjalankan metode ‘previous’ ketikan ‘tombolPrevious’ di klik
        self.tombolShow.triggered.connect(self.slideShow)  //menjalankan metode ‘slideShow’ ketika perintah ‘tombolShow’ di klik
        self.tombolHapus.triggered.connect(self.hapus)  //menjalankan metode ‘hapus’ ketika di klik ‘tombolHapus’
        self.tombolTentang.triggered.connect(self.tentang)  //menjalankan metode ‘tentang’ jika ‘tombolTentang’ di klik
        self.tombolRincian.triggered.connect(self.rincian)  //menjalankan metode ‘rincian’ jika ‘tombolRincian’ di klik

        self.tombolIn.setEnabled(False)  //mematikan ‘tombolIn’ (tombol perbesar)
        self.tombolOut.setEnabled(False)  //mematikan ‘tombolOut’ (tombol perkecil)
        self.tombolNormal.setEnabled(False)  //mematikan ‘tomboNormal’ (tombol Normal)
        self.tombolFit.setEnabled(False)  //mematikan ‘tomboFit’ (tombol Fit)
        self.tombolFull.setEnabled(False)  //mematikan ‘tomboFull’ (tombol Full)
        self.tombolNext.setEnabled(False)  //mematikan ‘tombolNext’
        self.tombolPrevious.setEnabled(False)  //mematikan ‘tombolPrevious’
        self.tombolShow.setEnabled(False)  //mematikan ‘tombolShow’
        self.tombolHapus.setEnabled(False)  //mematikan tombol ‘hapus’
        self.tombolRincian.setEnabled(False)  //mematikan ‘tombolRincian’

        self.toolBar.addSeparator()  //menambah garis pembatas
        self.toolBar.addAction(self.tombolBuka)  //memasukkan perintah ‘Buka’ (tombolBuka)
        self.toolBar.addSeparator()  //menambah garis pembatas
        self.toolBar.addAction(self.tombolIn)  //memasukkan perintah ‘In’ (perintah Perbesar) ke dalam toolbar
        self.toolBar.addAction(self.tombolOut)  //memasukkan perintah ‘Out’ (perintah Perkecil) ke dalam toolbar
        self.toolBar.addSeparator()  //menambah garis pembatas
        self.toolBar.addAction(self.tombolFull)  //memasukkan perintah ‘Full’ (tombol Full)
        self.toolBar.addAction(self.tombolShow)  //memasukkan ‘tombolShow’ ke dalam window
        self.toolBar.addSeparator()  //menambah garis pembatas
        self.toolBar.addAction(self.tombolNormal)  //memasukkan perintah ‘Normal’ (tombol Normal)
        self.toolBar.addAction(self.tombolFit)  //memasukkan perintah ‘Fit’ (tombol Fit)
        self.toolBar.addSeparator()  //menambah garis pembatas
        self.toolBar.addAction(self.tombolNext)  //memasukkan ‘tombolNext’ ke window
        self.toolBar.addAction(self.tombolPrevious)  //memasukkan ‘tombolPrevious’ ke window
        self.toolBar.addAction(self.tombolHapus)  //memasukkan perintah ‘tombolHapus’ ke dalam window
        self.toolBar.addAction(self.tombolRincian)  //memasukkan ‘tombolRincian’ ke dalam window
        self.toolBar.addSeparator()  //membuat garis pembatas
        self.toolBar.addAction(self.tombolTentang)  //memasukkan ‘tombolTentang’ ke dalam window
        self.toolBar.addSeparator()  //menambahkan garis

        self.layoutToolbar = QHBoxLayout()  //membuat layout toolbar
        self.layoutToolbar.addStretch()  //mebuat ‘stretch’ / karet yang akan memanjang ketika window di perbesar
        self.layoutToolbar.addWidget(self.toolBar)  //memasukkan layout toolbar ke window
        self.layoutToolbar.addStretch()  //mebuat ‘stretch’ / karet yang akan memanjang ketika window di perbesar
        self.layoutToolbar.setContentsMargins(0,0,0,0)  //membuat Layout Toolber tidak memiliki margin

        self.mainLayout.addLayout(self.layoutToolbar)  //memasukkan layout toolbar ke dalam window

    def perbesar(self):  //membuat metode perbesar
        self.ubahUkuran(1.25)  //memanggil metode ‘ubahUkuran’ dan memberikan nilai perbesaran (lebih dari 1)
        if self.ukuranGambar != 1 :  //mengecek apakah nilai variabel ‘ukuranGambar’ tidak bernilai 1
            self.tombolNormal.setEnabled(True)  //menghidupkan tombol normal
        else :  //jika nilai variabel ‘ukuranGambar’ adalah 1
            self.tombolNormal.setEnabled(False)  //mematikan tombol normal

    def perkecil(self):  //membuat metode ‘perkecil’
        self.ubahUkuran(0.8)  //memanggil metode ‘ubahUkuran’ dan memberikan nilai perkecilan (kurang dari 1)
        if self.ukuranGambar != 1 :  //mengecek apakah nilai variabel ‘ukuranGambar’ tidak bernilai 1
            self.tombolNormal.setEnabled(True)  //menghidupkan tombol normal
        else :  //jika nilai variabel ‘ukuranGambar’ adalah 1
            self.tombolNormal.setEnabled(False)  //mematikan tombol normal

    def ukuranNormal(self):  //membuat metode ‘ukuranNormal’
        self.tempatFoto.adjustSize()  //menormalkan ukuran foto
        self.sesuaikan()  //menjalankan metode ‘sesuaikan’
        self.ukuranGambar = 1.0  //mengubah nilai variabel ‘ukuranGambar’ menjadi 1
        self.tombolNormal.setEnabled(False)  //mematikan tombol normal

    def pasJendela(self):  //membuat metode ‘pasJendela’
        pasJendela = self.tombolFit.isChecked()  //mengecek apakah perintah ‘fit’ (tombolFit) tercentang. (true = tercentan dan false = tidak tercentang)
        self.scrollArea.setWidgetResizable(pasJendela)  //membuat window agar bisa di resize
        if not pasJendela:  //memastikan perintah ‘Fit’ (tombol Fit) tidak tecentang (karena ada not)
            self.ukuranNormal()  //menjalankan metode ‘ukuranNormal’
            self.tombolFit.setText('Fit')  //mengubah teks perintah ‘TombolFit’ (UnFit) menjadi ‘Fit’
        else :  //jika perintah ‘Fit’ (tombol Fit) tecentang
            self.tombolFit.setText('unFit')  //mengubah teks perintah ‘TombolFit’ (Fit) menjadi ‘UnFit’
        self.pengaktifTombol()  //menjalankan metode ‘pengaktifTombol’
        self.sesuaikan()  //menjalankan metode ‘sesuaikan’

    def ubahUkuran(self, factor):  //membuat metode ‘ubahUkuran’ dengan 1 buah parameter
        self.ukuranGambar *= factor  //mengalikan ukuran foto nilai parameter variabel ‘factor’
        self.tempatFoto.resize(self.ukuranGambar * self.tempatFoto.pixmap().size())  //mengubah ukuran foto
        self.tempatFoto.setAlignment(Qt.AlignRight)  //untuk mengubah align tempat foto

    def pengaktifTombol(self):  //membuat metode ‘pengaktifTombol’
        self.tombolIn.setEnabled(not self.tombolFit.isChecked())  //mematikan atau mematikan perintah ‘In’ (tombol in). (jika tombol ‘Fit’ hidup, maka hidup. Begitu sebaliknya)
        self.tombolOut.setEnabled(not self.tombolFit.isChecked())  //mematikan atau mematikan perintah ‘Out’ (tombol Out). (jika tombol ‘Fit’ hidup, maka hidup. Begitu sebaliknya)
        if self.ukuranGambar != 1 and self.tombolFit.isChecked() == False:  //memastikan variabel ‘ukuranGambar’ tidak sama dengan 1 dan tombo/perintah ‘Fit’ tidak tercentang. (Keduanya harus terpenuhi)
            self.tombolNormal.setEnabled(True)  //menghidupkan tombol/perintah ‘Normal’
        else :  //jika salah satu kondisi di atas salah satu tidak terpenuhi atau keduanya tidak terpenuhi
            self.tombolNormal.setEnabled(False)  //mematikan tombol/perintah ‘Normal’
        self.tombolFull.setEnabled(not self.tombolFit.isChecked())  //mematikan/menghidupkan tombol atau perintah ‘Fit’. (hidup jika tombol ‘Fit’ mati. Dan sebaliknya)

    def keyPressEvent(self, keyevent):  //metode yang akan di jalankan ketika user menekan keyboard atau mouse
        event = keyevent.key()  //mengambil event jika ada user menekan keyboard
        if event == Qt.Key_Escape:  //mengecek apakah tombol yang di klik adalah tombol ‘esc’
            self.tampilanPenuh()  //menjalankan metode ‘tampilanPenuh’
        if event == Qt.Key_A:  //mengecek apakah yang ditekan adalah tombol ‘A’
            self.previous()  //menjalankan metode ‘previous’
        if event == Qt.Key_D:  //mengecek apakah yang ditekan adalah tombol ‘D’
            self.next()  //menjalankan metode ‘next’
        if event == Qt.Key_W:  //mengecek apakah yang ditekan adalah tombol ‘W’
            self.tampilanPenuh()  //menjalankan metode ‘tampilanPenuh’

    def tampilanPenuh(self):  //membuat metode ‘penuh’
        if self.isFullScreen():  //mengecek apakah aplikasi dalam ke adaan fullscreen (false = normal screen dan True = fullscreen)
            self.showNormal()  //membuat window aplikasi menjadi normal
            self.updateTimer.stop()   //menghentikan timer
            self.toolBar.show() //menampilkan ‘toolbar’
            self.tombolFull.setText('Full')  //mengubah teks perintah ‘UnFull’ menjadi ‘Full’  (tombolFull)
        else:  //jika aplikasi tidak dalam keadaan fullscreen
            self.showFullScreen()  //membuat tampilan aplikasi menjadi full screen
            self.tombolFull.setText('unFull')  //mengubah teks perintah ‘Full’ menjadi ‘Unfull’ (tombolFull)

    def next(self):  //metode next
        if len(self.penampungLokasi) > 1 :  //memastikan item ‘penampungLokasi’ lebih dari 1
            if len(self.penampungLokasi)>self.posisi+1:  //memastikan item ‘PenampungLokas’ juga lebih dari nilai variabel ‘posisi’ ditambah 1
                self.posisi += 1  //menambah nilai ‘posisi’ sebanyak 1
            else:  //jika jumlah item ‘penampungLokasi’ tidak lebih kecil dari ‘posisi’ ditambah 1
                self.posisi = 0  //mengubah ‘posisi’ menjadi 0
            self.bukaGambar(self.penampungLokasi[self.posisi])  //membuka gambar dengan urutan sesuai dengan nilai posisi

    def previous(self):  //metode ‘previous’
        if len(self.penampungLokasi) > 1 :  //memastikan item ‘penampungLokasi’ lebih dari 1
            if 0 < self.posisi :  //memastikan nilai ‘posisi’ lebih dari 0
                self.posisi -= 1  //mengurangi nilai ‘posisi’ sebanyak 1
            else:  //jika nilai posisi adalah 0
                self.posisi = len(self.penampungLokasi)-1  //mengubah nilai posisi sesuai jumlah item ‘penampungLokasi’ di kurang 1

            self.bukaGambar(self.penampungLokasi[self.posisi])  //membuka gambar dengan urutan sesuai dengan nilai posisi

    def buka(self):  //membuat metode ‘buka’
        fileName,_ = QFileDialog.getOpenFileName(self, "Pilih File Gambar", QDir.currentPath(), filter="JPG (*.jpg);;PNG (*.png);;All (*.*) ")  //menampilkan file dialog untuk memilih file foto. Dan menyimpan lokasi foto yang di pilih user ke dalam variabel ‘fileName’

        if fileName:  //memastikan variabel ‘fileName’ tidak kosong (memastikan user memilih file)
            image = QImage(fileName)  //memuat foto
            if image.isNull():  //mengecek file apakah bukan file gambar
                QMessageBox.information(self, "Image Viewer",
                        "Maaf! tidak bisa membuka file --> %s." % os.path.basename(fileName))  //menampilkan kotak dialog peringatan jika user memilih file bukan gambar
                return  //menghentikan proses di metode ini

            self.bukaGambar(fileName)  //membuka file gambar yang di pilih user dengan memanggil metode ‘bukaGambar’ dan memasukkan lokasi gambar yang tersimpan di ‘fileName’

            lokasi = [os.path.dirname(fileName)]  //mendapatkan lokasi folder file foto yang di pilih user
            self.lokasiGambar(lokasi)  //menjalankan metode ‘lokasiGambar’ dengan memasukkan ‘lokasi’ sebagai parameter

            for i in range(len(self.penampungLokasi)) :  //melakukan perulangan sebanyak item ‘penampungLokasi’
                if self.penampungLokasi[i] == fileName :  //mengecek apakah file foto yang di pilih user ada di penampungLokasi (penampung file)
                    self.posisi = i  //mengubah nilai posisi sesuai dengan posisi gambar yang di pilih user
                    break  //menghentikan proses perulangan

            if len(self.penampungLokasi) > 1 :  //memastikan item di dalam ‘penampungLokasi’ lebih dari 1
                self.tombolNext.setEnabled(True)  //menghidupkan ‘tombolNext’
                self.tombolPrevious.setEnabled(True)  //menghidupkan ‘tombolPrevious’
                self.tombolShow.setEnabled(True)  //menghidupkan ‘tombolShow’
            else:
                self.tombolNext.setEnabled(False)  //menmatikan ‘tombolNext’
                self.tombolPrevious.setEnabled(False)  //mematikan ‘tombolPrevious’
                self.tombolShow.setEnabled(False)  //mematikan ‘tombolShow’

            self.tombolHapus.setEnabled(True)  //menghidupkan tombol hapus
            self.tombolFit.setEnabled(True)  //menghidupkan tombol/perintah ‘Fit’ (tombol Fit)
            self.tombolRincian.setEnabled(True)  //menghidupkan ‘tombolRincian’
            self.pengaktifTombol()  //menjalankan metode ‘pengaktifTombol’

    def fileValid(self, filename):  //membuat metode ‘fileValid’ untuk mengecek apakah file tersebut file foto dengan 1 parameter.
        if filename.endswith('PNG') or filename.endswith('png') or \
                filename.endswith('JPG') or filename.endswith('jpg'):  //mengecek apakah file nya ber ekstensi ‘jpg’ atau png
            return True  //digunakan untuk mengembalikan nilai ‘True’ jika file foto berekstensi ‘jpg’ atau ‘png’

    def lokasiGambar(self, lokasi):  //membuat metode ‘lokasiGambar’ untuk mendapatkan semua file foto di lokasi folder file foto yang di pilih user
        self.penampungLokasi = []  //mengosongkan ‘penampungLokasi’
        for gambar in lokasi:  //melakukan perulangan sebanyak item ‘lokasi’. Dan menampung setiap item di variabel ‘gambar’
            try:  //mencoba beberapa code program
                lokasiGambar = os.listdir(gambar)  //mematikan keberadaan gambar
            except OSError:  //jika ada eror di ‘try’
                raise OSError("Provided path '%s' doesn't exists." % gambar)  //mencetak pesan eror

            for lokasinya in lokasiGambar:  //melakukan perulangan sebanyak item di ‘lokasiGambar’
                item = os.path.join(gambar, lokasinya)  //menggabungkan lokasi dan nama foto
                if os.path.isfile(item) and self.fileValid(item):  //mengecek apakah path di ‘item’ adalah file dan memastikan file tersebut adalah file foto dengan menjalankan metode ‘fileValid’. Keduanya harus bernilai True
                    self.penampungLokasi.append(item)  //memasukkan ‘item’ ke ‘penampungLokasi’ jika memenuhi semua kriteria di atas
        return list(set(self.penampungLokasi))  //mengembalikan ‘penampungLokasi’

    def slideShow(self):  //metode ‘slideShow’
        self.connect(self.updateTimer, SIGNAL("timeout()"), self.next)  //menjalankan metode ‘next’ ketika penghitungan selesai
        self.showFullScreen()  //menampilkan layar penuh foto
        self.toolBar.hide()  //menyembunyikan ‘toolbar’
        self.updateTimer.start(4000)  //memulai perhitungan selama 4000 mili detik/ 4detik

    def hapus(self):  //membuat metode ‘hapus’
        if len(self.penampungLokasi) > 0 :  //memastikan penampung lokasi item nya lebih dari 0
            self.file = QFile(self.penampungLokasi[self.posisi])  //inisialisasi class ‘QFile’ dengan memasukkan path foto yang sedang di buka
            tombol1 = QMessageBox.StandardButton.Yes  ///membuat tombol yes
            tombol2 = QMessageBox.StandardButton.No  ///membuat tombol no
            pertanyaan = "anda yakin ingin menghapus permanen gambar ini?"  //membuat teks pertanyaan
            response = QMessageBox.question(self, "Question", pertanyaan, tombol1, tombol2)  //menampilkan kotak konfirmasi penghapusan
            if response == QMessageBox.Yes:  //mengecek apakah user mengkilik tombol ‘yes’
                self.file.remove()  //menghapus file
                self.penampungLokasi.pop(self.posisi)  //menghapus lokasi foto pada ‘punampungLokasi’
                if len(self.penampungLokasi) > 0 :  //mengeceka apakah penampung lebih dari 0 (ada foto lain dalam 1 folder)
                    self.next()  //menjalankan metode ‘next’
                    if len(self.penampungLokasi) == 1 :  //mengecek apakah item ‘penampungLokasi’ adalah 1
                        self.tombolNext.setEnabled(False)  //mematikan tombol ‘next’ jika penampungLokasi itemnya adalah 1
                        self.tombolPrevious.setEnabled(False)  //mematikan tombol ‘previous’ jika penampungLokasi itemnya adalah 1
                else :  //jika ‘penampungLokasi’ kosong
                    self.tempatFoto.setPixmap(None)  //mengosongkan penampil foto
                    self.tombolIn.setEnabled(False)  //mematikan ‘tombolIn’ (perbesar foto)
                    self.tombolOut.setEnabled(False)  //mematikan ‘tombolOut’ (perkecil foto)
                    self.tombolNormal.setEnabled(False)  //mematikan ‘tombolNormal’ (menormalkan ukuran foto)
                    self.tombolFit.setEnabled(False)  //mematikan ‘tombolFit’ (mengepaskan ukuran foto dengan window)
                    self.tombolFull.setEnabled(False)  //mematikan ‘tombolFull’ (fullscreen)
                    self.tombolNext.setEnabled(False)  //mematikan ‘tombolNext’ (foto selanjutnya)
                    self.tombolPrevious.setEnabled(False)  //mematikan ‘tombolPrefious’ (foto sebelumnya)
                    self.tombolShow.setEnabled(False)  //mematikan ‘tombolShow’ (slide show)
                    self.tombolHapus.setEnabled(False)  //mematikan ‘tombolHapus’ (menghapus foto)
                    self.tombolRincian.setEnabled(False)  //mematikan ‘tombolRincian’
                    self.setWindowTitle('Photo Viewer - mn-belajarpython.blogspot.co.id')  //mengubah judul window

def tentang(self):  //membuat metode ‘tentang’
        QMessageBox.information(self, "Tentang aplikasi",
                self.tr("Aplikasi ini merupakan sebuah apliakasi sederhana. "
                        "Namun, saya rasa aplikasi ini sudah cukup bagus "
                        "dari segi design. karena, didukung oleh modul yang "
                        "cukup lengkap dari PySide. sehingga saya hanya "
                        "menggunakannya saja\n"
                        "\nShortcut Tombol :"
                        "\n- esc / W \t : keluar/masuk dari fullscreen.\n"
                        "- A \t : gambar sebelumnya.\n"
                        "- D \t : gambar selanjutnya.\n"
                        "\nnah gimana ? menarikkan ? yuk kunjungi :  "
                        "mn-belajarpython.blogspot.co.id untuk tutorial "
                        "menarik lainnya..."))
//code di atas digunakan untuk menampilkan pesan tentang aplikasi (about application)


    def rincian(self):  //membuat metode ‘rincian’
        data = QFileInfo(self.penampungLokasi[self.posisi])  //memanggil class ‘QFileInfo’ dengan memasukkan lokasi file foto yang sedang dibuka sebagai parameter. Utnuk mendapatkan rincian foto
        QMessageBox.information(self, "Rincian", self.tr("Nama \t : "+str(data.baseName())+
                                                         "\nFormat \t : "+str(data.completeSuffix())+
                                                         "\nUkuran \t : "+str(data.size()/1000)+' Kb'+
                                                         "\nLokasi \t : "+str(data.path())+
                                                         "\nDibuat \t : "+str(data.created().toString('dddd, d MMMM yyyy || hh:mm:ss a'))+
                                                         "\nPemilik \t : "+str(data.owner())
                                                         ))
  //code di atas di gunakan untuk menampilkan rincian file foto yang sedang di buka


if __name__ == '__main__':  //code yang akan di jalankan pertama kali
    app = QApplication(sys.argv)  //insialisasi window
    app.setQuitOnLastWindowClosed(True)  //menutup window lain (aplikasi ini)
    window = PembukaFoto()  //menjalankan class ‘PembukaFoto’
    window.show()  //menampilkan window class ‘PembukaFoto’
    window.setGeometry(0,0,700,500)  //mengatur ukuran window
    window.setWindowTitle('Photo Viewer - mn-belajarpython.blogspot.co.id')  //mengubah judul window

    screen = QDesktopWidget().screenGeometry()  //mendapatkan ukuran layar monitor
    size = window.geometry()  //mendapat ukuran window aplikasi pembuka foto ini
    window.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)  //membuat window pembuka foto berada di tengah layar monitor


    sys.exit(app.exec_())  //agar window tidak langsung close saat di jalankan



Nah itu dia temen - temen penjelasan code programnya.. Mohon maaf ya apabila ada penjelasan yang kurang jelas, atau bahkan ada kekeliruan... Mohon kasi pembenaran atau pendapat kalian di kolom komentar ya temen - temen... Biar kita bisa belajar bersama - sama..

Oke terimakasih dan sampai di sini dulu ya temen - temen... Jangan lupa untuk membaca versi - versi yang lainnya... Biar ilmunya juga nambah.. Hehe.. Temikasih sekali lagi dan sekian...

Wassalamualaikum wr. wb.
Previous
Next Post »
Thanks for your comment