├── first ├── web.png ├── simple.py ├── icon.py ├── center.py ├── quit_button.py ├── tooltip.py └── messagebox.py ├── widgets ├── max.png ├── med.png ├── min.png ├── mute.png ├── check_box.py ├── calendar.py ├── slider.py ├── progressbar.py └── toggle_button.py ├── widgets2 ├── sid.jpg ├── pixmap.py ├── line_edit.py ├── combobox.py └── spitter.py ├── menustoolbars ├── exit24.png ├── submenu.py ├── context_menu.py ├── toolbar.py ├── simple_menu.py ├── check_menu.py └── main_window.py ├── datetime ├── julian_day.py ├── n_of_days.py ├── unix_time.py ├── utc_local.py ├── daylight_saving.py ├── xmas.py ├── current_date_time.py ├── battles.py └── arithmetic.py ├── README.md ├── events ├── reimplement_handler.py ├── emit_signal.py ├── signals_slots.py ├── event_sender.py └── event_object.py ├── layout ├── absolute.py ├── box_layout.py ├── calculator.py └── review.py ├── painting ├── bezier_curve.py ├── draw_text.py ├── draw_points.py ├── colours.py ├── pens.py └── brushes.py ├── dialogs ├── input_dialog.py ├── font_dialog.py ├── color_dialog.py └── file_dialog.py ├── dragdrop ├── simple_dragdrop.py └── drag_button.py ├── customwidget └── custom_widget.py └── tetris └── tetris.py /first/web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbodnar/PyQt5-Tutorial-Examples/HEAD/first/web.png -------------------------------------------------------------------------------- /widgets/max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbodnar/PyQt5-Tutorial-Examples/HEAD/widgets/max.png -------------------------------------------------------------------------------- /widgets/med.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbodnar/PyQt5-Tutorial-Examples/HEAD/widgets/med.png -------------------------------------------------------------------------------- /widgets/min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbodnar/PyQt5-Tutorial-Examples/HEAD/widgets/min.png -------------------------------------------------------------------------------- /widgets/mute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbodnar/PyQt5-Tutorial-Examples/HEAD/widgets/mute.png -------------------------------------------------------------------------------- /widgets2/sid.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbodnar/PyQt5-Tutorial-Examples/HEAD/widgets2/sid.jpg -------------------------------------------------------------------------------- /menustoolbars/exit24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbodnar/PyQt5-Tutorial-Examples/HEAD/menustoolbars/exit24.png -------------------------------------------------------------------------------- /datetime/julian_day.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from PyQt5.QtCore import QDate, Qt 4 | 5 | now = QDate.currentDate() 6 | 7 | print('Gregorian date for today:', now.toString(Qt.ISODate)) 8 | print('Julian day for today:', now.toJulianDay()) 9 | -------------------------------------------------------------------------------- /datetime/n_of_days.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from PyQt5.QtCore import QDate, Qt 4 | 5 | now = QDate.currentDate() 6 | 7 | d = QDate(1945, 5, 7) 8 | 9 | print(f'Days in month: {d.daysInMonth()}') 10 | print(f'Days in year: {d.daysInYear()}') 11 | -------------------------------------------------------------------------------- /datetime/unix_time.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from PyQt5.QtCore import QDateTime, Qt 4 | 5 | now = QDateTime.currentDateTime() 6 | 7 | unix_time = now.toSecsSinceEpoch() 8 | print(unix_time) 9 | 10 | d = QDateTime.fromSecsSinceEpoch(unix_time) 11 | print(d.toString(Qt.ISODate)) 12 | -------------------------------------------------------------------------------- /datetime/utc_local.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from PyQt5.QtCore import QDateTime, Qt 4 | 5 | now = QDateTime.currentDateTime() 6 | 7 | print('Local datetime: ', now.toString(Qt.ISODate)) 8 | print('Universal datetime: ', now.toUTC().toString(Qt.ISODate)) 9 | 10 | print(f'The offset from UTC is: {now.offsetFromUtc()} seconds') 11 | -------------------------------------------------------------------------------- /datetime/daylight_saving.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from PyQt5.QtCore import QDateTime, QTimeZone, Qt 4 | 5 | now = QDateTime.currentDateTime() 6 | 7 | print(f'Time zone: {now.timeZoneAbbreviation()}') 8 | 9 | if now.isDaylightTime(): 10 | print(f'The current date falls into DST time') 11 | else: 12 | print(f'The current date does not fall into DST time') 13 | -------------------------------------------------------------------------------- /datetime/xmas.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from PyQt5.QtCore import QDate 4 | 5 | xmas1 = QDate(2019, 12, 24) 6 | xmas2 = QDate(2020, 12, 24) 7 | 8 | now = QDate.currentDate() 9 | 10 | dayspassed = xmas1.daysTo(now) 11 | print(f'{dayspassed} days have passed since last XMas') 12 | 13 | nofdays = now.daysTo(xmas2) 14 | print(f'There are {nofdays} days until next XMas') 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyQt-Tutorial-Examples 2 | Sources and images for ZetCode's [PyQt5 tutorial](http://zetcode.com/gui/pyqt5/) 3 | 4 | There are additional more in-depth tutorials: [PyQt tutorials](http://zetcode.com/all/#pyqt) 5 | with their own [PyQt-Examples](https://github.com/janbodnar/PyQt-Examples) repository. 6 | 7 | 8 | Author's [Advanced PyQt5 e-book](http://zetcode.com/ebooks/advancedpyqt5/) 9 | -------------------------------------------------------------------------------- /datetime/current_date_time.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from PyQt5.QtCore import QDate, QTime, QDateTime, Qt 4 | 5 | now = QDate.currentDate() 6 | 7 | print(now.toString(Qt.ISODate)) 8 | print(now.toString(Qt.DefaultLocaleLongDate)) 9 | 10 | datetime = QDateTime.currentDateTime() 11 | 12 | print(datetime.toString()) 13 | 14 | time = QTime.currentTime() 15 | 16 | print(time.toString(Qt.DefaultLocaleLongDate)) 17 | -------------------------------------------------------------------------------- /datetime/battles.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from PyQt5.QtCore import QDate, Qt 4 | 5 | borodino_battle = QDate(1812, 9, 7) 6 | slavkov_battle = QDate(1805, 12, 2) 7 | 8 | now = QDate.currentDate() 9 | 10 | j_today = now.toJulianDay() 11 | j_borodino = borodino_battle.toJulianDay() 12 | j_slavkov = slavkov_battle.toJulianDay() 13 | 14 | d1 = j_today - j_slavkov 15 | d2 = j_today - j_borodino 16 | 17 | print(f'Days since Slavkov battle: {d1}') 18 | print(f'Days since Borodino battle: {d2}') 19 | -------------------------------------------------------------------------------- /datetime/arithmetic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from PyQt5.QtCore import QDateTime, Qt 4 | 5 | now = QDateTime.currentDateTime() 6 | 7 | print(f'Today:', now.toString(Qt.ISODate)) 8 | print(f'Adding 12 days: {now.addDays(12).toString(Qt.ISODate)}') 9 | print(f'Subtracting 22 days: {now.addDays(-22).toString(Qt.ISODate)}') 10 | 11 | print(f'Adding 50 seconds: {now.addSecs(50).toString(Qt.ISODate)}') 12 | print(f'Adding 3 months: {now.addMonths(3).toString(Qt.ISODate)}') 13 | print(f'Adding 12 years: {now.addYears(12).toString(Qt.ISODate)}') 14 | -------------------------------------------------------------------------------- /first/simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we create a simple 7 | window in PyQt5. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtWidgets import QApplication, QWidget 15 | 16 | 17 | def main(): 18 | 19 | app = QApplication(sys.argv) 20 | 21 | w = QWidget() 22 | w.resize(250, 150) 23 | w.move(300, 300) 24 | w.setWindowTitle('Simple') 25 | w.show() 26 | 27 | sys.exit(app.exec_()) 28 | 29 | 30 | if __name__ == '__main__': 31 | main() 32 | -------------------------------------------------------------------------------- /first/icon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This example shows an icon 7 | in the titlebar of the window. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtWidgets import QApplication, QWidget 15 | from PyQt5.QtGui import QIcon 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | 26 | def initUI(self): 27 | 28 | self.setGeometry(300, 300, 300, 220) 29 | self.setWindowTitle('Icon') 30 | self.setWindowIcon(QIcon('web.png')) 31 | 32 | self.show() 33 | 34 | 35 | def main(): 36 | 37 | app = QApplication(sys.argv) 38 | ex = Example() 39 | sys.exit(app.exec_()) 40 | 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /events/reimplement_handler.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we reimplement an 7 | event handler. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtCore import Qt 15 | from PyQt5.QtWidgets import QWidget, QApplication 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | self.setGeometry(300, 300, 250, 150) 27 | self.setWindowTitle('Event handler') 28 | self.show() 29 | 30 | def keyPressEvent(self, e): 31 | if e.key() == Qt.Key_Escape: 32 | self.close() 33 | 34 | 35 | def main(): 36 | app = QApplication(sys.argv) 37 | ex = Example() 38 | sys.exit(app.exec_()) 39 | 40 | 41 | if __name__ == '__main__': 42 | main() 43 | -------------------------------------------------------------------------------- /first/center.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This program centers a window 7 | on the screen. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtWidgets import QWidget, QDesktopWidget, QApplication 15 | 16 | 17 | class Example(QWidget): 18 | 19 | def __init__(self): 20 | super().__init__() 21 | 22 | self.initUI() 23 | 24 | def initUI(self): 25 | 26 | self.resize(250, 150) 27 | self.center() 28 | 29 | self.setWindowTitle('Center') 30 | self.show() 31 | 32 | def center(self): 33 | 34 | qr = self.frameGeometry() 35 | cp = QDesktopWidget().availableGeometry().center() 36 | qr.moveCenter(cp) 37 | self.move(qr.topLeft()) 38 | 39 | 40 | def main(): 41 | 42 | app = QApplication(sys.argv) 43 | ex = Example() 44 | sys.exit(app.exec_()) 45 | 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /first/quit_button.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This program creates a quit 7 | button. When we press the button, 8 | the application terminates. 9 | 10 | Author: Jan Bodnar 11 | Website: zetcode.com 12 | """ 13 | 14 | import sys 15 | from PyQt5.QtWidgets import QWidget, QPushButton, QApplication 16 | 17 | class Example(QWidget): 18 | 19 | def __init__(self): 20 | super().__init__() 21 | 22 | self.initUI() 23 | 24 | 25 | def initUI(self): 26 | 27 | qbtn = QPushButton('Quit', self) 28 | qbtn.clicked.connect(QApplication.instance().quit) 29 | qbtn.resize(qbtn.sizeHint()) 30 | qbtn.move(50, 50) 31 | 32 | self.setGeometry(300, 300, 350, 250) 33 | self.setWindowTitle('Quit button') 34 | self.show() 35 | 36 | 37 | def main(): 38 | 39 | app = QApplication(sys.argv) 40 | ex = Example() 41 | sys.exit(app.exec_()) 42 | 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /layout/absolute.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This example shows three labels on a window 7 | using absolute positioning. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtWidgets import QWidget, QLabel, QApplication 15 | 16 | 17 | class Example(QWidget): 18 | 19 | def __init__(self): 20 | super().__init__() 21 | 22 | self.initUI() 23 | 24 | def initUI(self): 25 | lbl1 = QLabel('ZetCode', self) 26 | lbl1.move(15, 10) 27 | 28 | lbl2 = QLabel('tutorials', self) 29 | lbl2.move(35, 40) 30 | 31 | lbl3 = QLabel('for programmers', self) 32 | lbl3.move(55, 70) 33 | 34 | self.setGeometry(300, 300, 250, 150) 35 | self.setWindowTitle('Absolute') 36 | self.show() 37 | 38 | 39 | def main(): 40 | app = QApplication(sys.argv) 41 | ex = Example() 42 | sys.exit(app.exec_()) 43 | 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /widgets2/pixmap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we display an image 7 | on the window. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | from PyQt5.QtWidgets import (QWidget, QHBoxLayout, 14 | QLabel, QApplication) 15 | from PyQt5.QtGui import QPixmap 16 | import sys 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | def initUI(self): 27 | hbox = QHBoxLayout(self) 28 | pixmap = QPixmap('sid.jpg') 29 | 30 | lbl = QLabel(self) 31 | lbl.setPixmap(pixmap) 32 | 33 | hbox.addWidget(lbl) 34 | self.setLayout(hbox) 35 | 36 | self.move(300, 200) 37 | self.setWindowTitle('Sid') 38 | self.show() 39 | 40 | 41 | def main(): 42 | app = QApplication(sys.argv) 43 | ex = Example() 44 | sys.exit(app.exec_()) 45 | 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /events/emit_signal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we show how to 7 | emit a custom signal. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtCore import pyqtSignal, QObject 15 | from PyQt5.QtWidgets import QMainWindow, QApplication 16 | 17 | 18 | class Communicate(QObject): 19 | 20 | closeApp = pyqtSignal() 21 | 22 | 23 | class Example(QMainWindow): 24 | 25 | def __init__(self): 26 | super().__init__() 27 | 28 | self.initUI() 29 | 30 | def initUI(self): 31 | 32 | self.c = Communicate() 33 | self.c.closeApp.connect(self.close) 34 | 35 | self.setGeometry(300, 300, 450, 350) 36 | self.setWindowTitle('Emit signal') 37 | self.show() 38 | 39 | def mousePressEvent(self, event): 40 | 41 | self.c.closeApp.emit() 42 | 43 | 44 | def main(): 45 | app = QApplication(sys.argv) 46 | ex = Example() 47 | sys.exit(app.exec_()) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /menustoolbars/submenu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This program creates a submenu. 7 | 8 | Author: Jan Bodnar 9 | Website: zetcode.com 10 | """ 11 | 12 | import sys 13 | from PyQt5.QtWidgets import QMainWindow, QAction, QMenu, QApplication 14 | 15 | 16 | class Example(QMainWindow): 17 | 18 | def __init__(self): 19 | super().__init__() 20 | 21 | self.initUI() 22 | 23 | def initUI(self): 24 | 25 | menubar = self.menuBar() 26 | fileMenu = menubar.addMenu('File') 27 | 28 | impMenu = QMenu('Import', self) 29 | impAct = QAction('Import mail', self) 30 | impMenu.addAction(impAct) 31 | 32 | newAct = QAction('New', self) 33 | 34 | fileMenu.addAction(newAct) 35 | fileMenu.addMenu(impMenu) 36 | 37 | self.setGeometry(300, 300, 300, 200) 38 | self.setWindowTitle('Submenu') 39 | self.show() 40 | 41 | 42 | def main(): 43 | app = QApplication(sys.argv) 44 | ex = Example() 45 | sys.exit(app.exec_()) 46 | 47 | 48 | if __name__ == '__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /menustoolbars/context_menu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This program creates a context menu. 7 | 8 | Author: Jan Bodnar 9 | Website: zetcode.com 10 | """ 11 | 12 | import sys 13 | from PyQt5.QtWidgets import QMainWindow, qApp, QMenu, QApplication 14 | 15 | 16 | class Example(QMainWindow): 17 | 18 | def __init__(self): 19 | super().__init__() 20 | 21 | self.initUI() 22 | 23 | def initUI(self): 24 | self.setGeometry(300, 300, 300, 200) 25 | self.setWindowTitle('Context menu') 26 | self.show() 27 | 28 | def contextMenuEvent(self, event): 29 | cmenu = QMenu(self) 30 | 31 | newAct = cmenu.addAction("New") 32 | openAct = cmenu.addAction("Open") 33 | quitAct = cmenu.addAction("Quit") 34 | action = cmenu.exec_(self.mapToGlobal(event.pos())) 35 | 36 | if action == quitAct: 37 | qApp.quit() 38 | 39 | 40 | def main(): 41 | app = QApplication(sys.argv) 42 | ex = Example() 43 | sys.exit(app.exec_()) 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /menustoolbars/toolbar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This program creates a toolbar. 7 | The toolbar has one action, which 8 | terminates the application, if triggered. 9 | 10 | Author: Jan Bodnar 11 | Website: zetcode.com 12 | """ 13 | 14 | import sys 15 | from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication 16 | from PyQt5.QtGui import QIcon 17 | 18 | 19 | class Example(QMainWindow): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | 27 | def initUI(self): 28 | 29 | exitAct = QAction(QIcon('exit24.png'), 'Exit', self) 30 | exitAct.setShortcut('Ctrl+Q') 31 | exitAct.triggered.connect(qApp.quit) 32 | 33 | self.toolbar = self.addToolBar('Exit') 34 | self.toolbar.addAction(exitAct) 35 | 36 | self.setGeometry(300, 300, 300, 200) 37 | self.setWindowTitle('Toolbar') 38 | self.show() 39 | 40 | 41 | def main(): 42 | app = QApplication(sys.argv) 43 | ex = Example() 44 | sys.exit(app.exec_()) 45 | 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /first/tooltip.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This example shows a tooltip on 7 | a window and a button. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtWidgets import (QWidget, QToolTip, 15 | QPushButton, QApplication) 16 | from PyQt5.QtGui import QFont 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | 27 | def initUI(self): 28 | 29 | QToolTip.setFont(QFont('SansSerif', 10)) 30 | 31 | self.setToolTip('This is a QWidget widget') 32 | 33 | btn = QPushButton('Button', self) 34 | btn.setToolTip('This is a QPushButton widget') 35 | btn.resize(btn.sizeHint()) 36 | btn.move(50, 50) 37 | 38 | self.setGeometry(300, 300, 300, 200) 39 | self.setWindowTitle('Tooltips') 40 | self.show() 41 | 42 | 43 | def main(): 44 | 45 | app = QApplication(sys.argv) 46 | ex = Example() 47 | sys.exit(app.exec_()) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /widgets2/line_edit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This example shows text which 7 | is entered in a QLineEdit 8 | in a QLabel widget. 9 | 10 | Author: Jan Bodnar 11 | Website: zetcode.com 12 | """ 13 | 14 | import sys 15 | from PyQt5.QtWidgets import (QWidget, QLabel, 16 | QLineEdit, QApplication) 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | def initUI(self): 27 | self.lbl = QLabel(self) 28 | qle = QLineEdit(self) 29 | 30 | qle.move(60, 100) 31 | self.lbl.move(60, 40) 32 | 33 | qle.textChanged[str].connect(self.onChanged) 34 | 35 | self.setGeometry(300, 300, 350, 250) 36 | self.setWindowTitle('QLineEdit') 37 | self.show() 38 | 39 | def onChanged(self, text): 40 | self.lbl.setText(text) 41 | self.lbl.adjustSize() 42 | 43 | 44 | def main(): 45 | app = QApplication(sys.argv) 46 | ex = Example() 47 | sys.exit(app.exec_()) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /events/signals_slots.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we connect a signal 7 | of a QSlider to a slot of a QLCDNumber. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtCore import Qt 15 | from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider, 16 | QVBoxLayout, QApplication) 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | 27 | def initUI(self): 28 | 29 | lcd = QLCDNumber(self) 30 | sld = QSlider(Qt.Horizontal, self) 31 | 32 | vbox = QVBoxLayout() 33 | vbox.addWidget(lcd) 34 | vbox.addWidget(sld) 35 | 36 | self.setLayout(vbox) 37 | sld.valueChanged.connect(lcd.display) 38 | 39 | self.setGeometry(300, 300, 250, 150) 40 | self.setWindowTitle('Signal and slot') 41 | self.show() 42 | 43 | 44 | def main(): 45 | app = QApplication(sys.argv) 46 | ex = Example() 47 | sys.exit(app.exec_()) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /widgets/check_box.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, a QCheckBox widget 7 | is used to toggle the title of a window. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | from PyQt5.QtWidgets import QWidget, QCheckBox, QApplication 14 | from PyQt5.QtCore import Qt 15 | import sys 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | 27 | cb = QCheckBox('Show title', self) 28 | cb.move(20, 20) 29 | cb.toggle() 30 | cb.stateChanged.connect(self.changeTitle) 31 | 32 | self.setGeometry(300, 300, 350, 250) 33 | self.setWindowTitle('QCheckBox') 34 | self.show() 35 | 36 | def changeTitle(self, state): 37 | 38 | if state == Qt.Checked: 39 | self.setWindowTitle('QCheckBox') 40 | else: 41 | self.setWindowTitle(' ') 42 | 43 | 44 | def main(): 45 | app = QApplication(sys.argv) 46 | ex = Example() 47 | sys.exit(app.exec_()) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /menustoolbars/simple_menu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This program creates a menubar. The 7 | menubar has one menu with an exit action. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication 15 | from PyQt5.QtGui import QIcon 16 | 17 | 18 | class Example(QMainWindow): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | 27 | exitAct = QAction(QIcon('exit.png'), '&Exit', self) 28 | exitAct.setShortcut('Ctrl+Q') 29 | exitAct.setStatusTip('Exit application') 30 | exitAct.triggered.connect(qApp.quit) 31 | 32 | self.statusBar() 33 | 34 | menubar = self.menuBar() 35 | fileMenu = menubar.addMenu('&File') 36 | fileMenu.addAction(exitAct) 37 | 38 | self.setGeometry(300, 300, 300, 200) 39 | self.setWindowTitle('Simple menu') 40 | self.show() 41 | 42 | 43 | def main(): 44 | app = QApplication(sys.argv) 45 | ex = Example() 46 | sys.exit(app.exec_()) 47 | 48 | 49 | if __name__ == '__main__': 50 | main() 51 | -------------------------------------------------------------------------------- /painting/bezier_curve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This program draws a Bézier curve with 7 | QPainterPath. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | 15 | from PyQt5.QtGui import QPainter, QPainterPath 16 | from PyQt5.QtWidgets import QWidget, QApplication 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | def initUI(self): 27 | self.setGeometry(300, 300, 380, 250) 28 | self.setWindowTitle('Bézier curve') 29 | self.show() 30 | 31 | def paintEvent(self, e): 32 | qp = QPainter() 33 | qp.begin(self) 34 | qp.setRenderHint(QPainter.Antialiasing) 35 | self.drawBezierCurve(qp) 36 | qp.end() 37 | 38 | def drawBezierCurve(self, qp): 39 | path = QPainterPath() 40 | path.moveTo(30, 30) 41 | path.cubicTo(30, 30, 200, 350, 350, 30) 42 | 43 | qp.drawPath(path) 44 | 45 | 46 | def main(): 47 | 48 | app = QApplication(sys.argv) 49 | ex = Example() 50 | sys.exit(app.exec_()) 51 | 52 | 53 | if __name__ == '__main__': 54 | main() 55 | -------------------------------------------------------------------------------- /first/messagebox.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This program shows a confirmation 7 | message box when we click on the close 8 | button of the application window. 9 | 10 | Author: Jan Bodnar 11 | Website: zetcode.com 12 | """ 13 | 14 | import sys 15 | from PyQt5.QtWidgets import QWidget, QMessageBox, QApplication 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | 27 | self.setGeometry(300, 300, 250, 150) 28 | self.setWindowTitle('Message box') 29 | self.show() 30 | 31 | def closeEvent(self, event): 32 | 33 | reply = QMessageBox.question(self, 'Message', 34 | "Are you sure to quit?", QMessageBox.Yes | 35 | QMessageBox.No, QMessageBox.No) 36 | 37 | if reply == QMessageBox.Yes: 38 | 39 | event.accept() 40 | else: 41 | 42 | event.ignore() 43 | 44 | 45 | def main(): 46 | app = QApplication(sys.argv) 47 | ex = Example() 48 | sys.exit(app.exec_()) 49 | 50 | 51 | if __name__ == '__main__': 52 | main() 53 | -------------------------------------------------------------------------------- /events/event_sender.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we determine the event sender 7 | object. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication 15 | 16 | 17 | class Example(QMainWindow): 18 | 19 | def __init__(self): 20 | super().__init__() 21 | 22 | self.initUI() 23 | 24 | def initUI(self): 25 | btn1 = QPushButton("Button 1", self) 26 | btn1.move(30, 50) 27 | 28 | btn2 = QPushButton("Button 2", self) 29 | btn2.move(150, 50) 30 | 31 | btn1.clicked.connect(self.buttonClicked) 32 | btn2.clicked.connect(self.buttonClicked) 33 | 34 | self.statusBar() 35 | 36 | self.setGeometry(300, 300, 450, 350) 37 | self.setWindowTitle('Event sender') 38 | self.show() 39 | 40 | def buttonClicked(self): 41 | sender = self.sender() 42 | self.statusBar().showMessage(sender.text() + ' was pressed') 43 | 44 | 45 | def main(): 46 | app = QApplication(sys.argv) 47 | ex = Example() 48 | sys.exit(app.exec_()) 49 | 50 | 51 | if __name__ == '__main__': 52 | main() 53 | -------------------------------------------------------------------------------- /layout/box_layout.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we position two push 7 | buttons in the bottom-right corner 8 | of the window. 9 | 10 | Author: Jan Bodnar 11 | Website: zetcode.com 12 | """ 13 | 14 | import sys 15 | from PyQt5.QtWidgets import (QWidget, QPushButton, 16 | QHBoxLayout, QVBoxLayout, QApplication) 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | def initUI(self): 27 | 28 | okButton = QPushButton("OK") 29 | cancelButton = QPushButton("Cancel") 30 | 31 | hbox = QHBoxLayout() 32 | hbox.addStretch(1) 33 | hbox.addWidget(okButton) 34 | hbox.addWidget(cancelButton) 35 | 36 | vbox = QVBoxLayout() 37 | vbox.addStretch(1) 38 | vbox.addLayout(hbox) 39 | 40 | self.setLayout(vbox) 41 | 42 | self.setGeometry(300, 300, 300, 150) 43 | self.setWindowTitle('Buttons') 44 | self.show() 45 | 46 | 47 | def main(): 48 | app = QApplication(sys.argv) 49 | ex = Example() 50 | sys.exit(app.exec_()) 51 | 52 | 53 | if __name__ == '__main__': 54 | main() 55 | -------------------------------------------------------------------------------- /painting/draw_text.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we draw text in Russian Cylliric. 7 | 8 | Author: Jan Bodnar 9 | Website: zetcode.com 10 | """ 11 | 12 | import sys 13 | from PyQt5.QtWidgets import QWidget, QApplication 14 | from PyQt5.QtGui import QPainter, QColor, QFont 15 | from PyQt5.QtCore import Qt 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | 27 | self.text = "Лев Николаевич Толстой\nАнна Каренина" 28 | 29 | self.setGeometry(300, 300, 350, 300) 30 | self.setWindowTitle('Drawing text') 31 | self.show() 32 | 33 | def paintEvent(self, event): 34 | qp = QPainter() 35 | qp.begin(self) 36 | self.drawText(event, qp) 37 | qp.end() 38 | 39 | def drawText(self, event, qp): 40 | qp.setPen(QColor(168, 34, 3)) 41 | qp.setFont(QFont('Decorative', 10)) 42 | qp.drawText(event.rect(), Qt.AlignCenter, self.text) 43 | 44 | 45 | def main(): 46 | 47 | app = QApplication(sys.argv) 48 | ex = Example() 49 | sys.exit(app.exec_()) 50 | 51 | 52 | if __name__ == '__main__': 53 | main() 54 | -------------------------------------------------------------------------------- /dialogs/input_dialog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we receive data from 7 | a QInputDialog dialog. 8 | 9 | Aauthor: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | from PyQt5.QtWidgets import (QWidget, QPushButton, QLineEdit, 14 | QInputDialog, QApplication) 15 | import sys 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | self.btn = QPushButton('Dialog', self) 27 | self.btn.move(20, 20) 28 | self.btn.clicked.connect(self.showDialog) 29 | 30 | self.le = QLineEdit(self) 31 | self.le.move(130, 22) 32 | 33 | self.setGeometry(300, 300, 450, 350) 34 | self.setWindowTitle('Input dialog') 35 | self.show() 36 | 37 | def showDialog(self): 38 | text, ok = QInputDialog.getText(self, 'Input Dialog', 39 | 'Enter your name:') 40 | 41 | if ok: 42 | self.le.setText(str(text)) 43 | 44 | 45 | def main(): 46 | app = QApplication(sys.argv) 47 | ex = Example() 48 | sys.exit(app.exec_()) 49 | 50 | 51 | if __name__ == '__main__': 52 | main() 53 | -------------------------------------------------------------------------------- /widgets2/combobox.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This example shows how to use 7 | a QComboBox widget. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | 15 | from PyQt5.QtWidgets import (QWidget, QLabel, 16 | QComboBox, QApplication) 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | def initUI(self): 27 | 28 | self.lbl = QLabel('Ubuntu', self) 29 | 30 | combo = QComboBox(self) 31 | combo.addItem('Ubuntu') 32 | combo.addItem('Mandriva') 33 | combo.addItem('Fedora') 34 | combo.addItem('Arch') 35 | combo.addItem('Gentoo') 36 | 37 | combo.move(50, 50) 38 | self.lbl.move(50, 150) 39 | 40 | combo.activated[str].connect(self.onActivated) 41 | 42 | self.setGeometry(300, 300, 450, 400) 43 | self.setWindowTitle('QComboBox') 44 | self.show() 45 | 46 | def onActivated(self, text): 47 | self.lbl.setText(text) 48 | self.lbl.adjustSize() 49 | 50 | 51 | def main(): 52 | app = QApplication(sys.argv) 53 | ex = Example() 54 | sys.exit(app.exec_()) 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /events/event_object.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we display the x and y 7 | coordinates of a mouse pointer in a label widget. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtCore import Qt 15 | from PyQt5.QtWidgets import QWidget, QApplication, QGridLayout, QLabel 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | grid = QGridLayout() 27 | 28 | x = 0 29 | y = 0 30 | 31 | self.text = f'x: {x}, y: {y}' 32 | 33 | self.label = QLabel(self.text, self) 34 | grid.addWidget(self.label, 0, 0, Qt.AlignTop) 35 | 36 | self.setMouseTracking(True) 37 | 38 | self.setLayout(grid) 39 | 40 | self.setGeometry(300, 300, 450, 300) 41 | self.setWindowTitle('Event object') 42 | self.show() 43 | 44 | def mouseMoveEvent(self, e): 45 | x = e.x() 46 | y = e.y() 47 | 48 | text = f'x: {x}, y: {y}' 49 | self.label.setText(text) 50 | 51 | 52 | def main(): 53 | app = QApplication(sys.argv) 54 | ex = Example() 55 | sys.exit(app.exec_()) 56 | 57 | 58 | if __name__ == '__main__': 59 | main() 60 | -------------------------------------------------------------------------------- /widgets/calendar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This example shows a QCalendarWidget widget. 7 | 8 | Author: Jan Bodnar 9 | Website: zetcode.com 10 | """ 11 | 12 | from PyQt5.QtWidgets import (QWidget, QCalendarWidget, 13 | QLabel, QApplication, QVBoxLayout) 14 | from PyQt5.QtCore import QDate 15 | import sys 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | vbox = QVBoxLayout(self) 27 | 28 | cal = QCalendarWidget(self) 29 | cal.setGridVisible(True) 30 | cal.clicked[QDate].connect(self.showDate) 31 | 32 | vbox.addWidget(cal) 33 | 34 | self.lbl = QLabel(self) 35 | date = cal.selectedDate() 36 | self.lbl.setText(date.toString()) 37 | 38 | vbox.addWidget(self.lbl) 39 | 40 | self.setLayout(vbox) 41 | 42 | self.setGeometry(300, 300, 350, 300) 43 | self.setWindowTitle('Calendar') 44 | self.show() 45 | 46 | def showDate(self, date): 47 | self.lbl.setText(date.toString()) 48 | 49 | 50 | def main(): 51 | app = QApplication(sys.argv) 52 | ex = Example() 53 | sys.exit(app.exec_()) 54 | 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /painting/draw_points.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In the example, we draw randomly 1000 red points 7 | on the window. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | from PyQt5.QtWidgets import QWidget, QApplication 14 | from PyQt5.QtGui import QPainter 15 | from PyQt5.QtCore import Qt 16 | import sys, random 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | def initUI(self): 27 | self.setGeometry(300, 300, 300, 190) 28 | self.setWindowTitle('Points') 29 | self.show() 30 | 31 | def paintEvent(self, e): 32 | qp = QPainter() 33 | qp.begin(self) 34 | self.drawPoints(qp) 35 | qp.end() 36 | 37 | def drawPoints(self, qp): 38 | qp.setPen(Qt.red) 39 | size = self.size() 40 | 41 | if size.height() <= 1 or size.height() <= 1: 42 | return 43 | 44 | for i in range(1000): 45 | x = random.randint(1, size.width() - 1) 46 | y = random.randint(1, size.height() - 1) 47 | qp.drawPoint(x, y) 48 | 49 | 50 | def main(): 51 | app = QApplication(sys.argv) 52 | ex = Example() 53 | sys.exit(app.exec_()) 54 | 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /painting/colours.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This example draws three rectangles in three 7 | different colours. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | from PyQt5.QtWidgets import QWidget, QApplication 14 | from PyQt5.QtGui import QPainter, QColor, QBrush 15 | import sys 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | self.setGeometry(300, 300, 350, 100) 27 | self.setWindowTitle('Colours') 28 | self.show() 29 | 30 | def paintEvent(self, e): 31 | qp = QPainter() 32 | qp.begin(self) 33 | self.drawRectangles(qp) 34 | qp.end() 35 | 36 | def drawRectangles(self, qp): 37 | col = QColor(0, 0, 0) 38 | col.setNamedColor('#d4d4d4') 39 | qp.setPen(col) 40 | 41 | qp.setBrush(QColor(200, 0, 0)) 42 | qp.drawRect(10, 15, 90, 60) 43 | 44 | qp.setBrush(QColor(255, 80, 0, 160)) 45 | qp.drawRect(130, 15, 90, 60) 46 | 47 | qp.setBrush(QColor(25, 0, 90, 200)) 48 | qp.drawRect(250, 15, 90, 60) 49 | 50 | 51 | def main(): 52 | app = QApplication(sys.argv) 53 | ex = Example() 54 | sys.exit(app.exec_()) 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /layout/calculator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we create a skeleton 7 | of a calculator using QGridLayout. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | from PyQt5.QtWidgets import (QWidget, QGridLayout, 15 | QPushButton, QApplication) 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | 27 | grid = QGridLayout() 28 | self.setLayout(grid) 29 | 30 | names = ['Cls', 'Bck', '', 'Close', 31 | '7', '8', '9', '/', 32 | '4', '5', '6', '*', 33 | '1', '2', '3', '-', 34 | '0', '.', '=', '+'] 35 | 36 | positions = [(i, j) for i in range(5) for j in range(4)] 37 | 38 | for position, name in zip(positions, names): 39 | 40 | if name == '': 41 | continue 42 | button = QPushButton(name) 43 | grid.addWidget(button, *position) 44 | 45 | self.move(300, 150) 46 | self.setWindowTitle('Calculator') 47 | self.show() 48 | 49 | 50 | def main(): 51 | app = QApplication(sys.argv) 52 | ex = Example() 53 | sys.exit(app.exec_()) 54 | 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /menustoolbars/check_menu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This program creates a checkable menu. 7 | 8 | Author: Jan Bodnar 9 | Website: zetcode.com 10 | """ 11 | 12 | import sys 13 | from PyQt5.QtWidgets import QMainWindow, QAction, QApplication 14 | 15 | 16 | class Example(QMainWindow): 17 | 18 | def __init__(self): 19 | super().__init__() 20 | 21 | self.initUI() 22 | 23 | 24 | def initUI(self): 25 | 26 | self.statusbar = self.statusBar() 27 | self.statusbar.showMessage('Ready') 28 | 29 | menubar = self.menuBar() 30 | viewMenu = menubar.addMenu('View') 31 | 32 | viewStatAct = QAction('View statusbar', self, checkable=True) 33 | viewStatAct.setStatusTip('View statusbar') 34 | viewStatAct.setChecked(True) 35 | viewStatAct.triggered.connect(self.toggleMenu) 36 | 37 | viewMenu.addAction(viewStatAct) 38 | 39 | self.setGeometry(300, 300, 300, 200) 40 | self.setWindowTitle('Check menu') 41 | self.show() 42 | 43 | def toggleMenu(self, state): 44 | 45 | if state: 46 | self.statusbar.show() 47 | else: 48 | self.statusbar.hide() 49 | 50 | 51 | def main(): 52 | app = QApplication(sys.argv) 53 | ex = Example() 54 | sys.exit(app.exec_()) 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /dragdrop/simple_dragdrop.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This is a simple drag and 7 | drop example. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | 15 | from PyQt5.QtWidgets import (QPushButton, QWidget, 16 | QLineEdit, QApplication) 17 | 18 | 19 | class Button(QPushButton): 20 | 21 | def __init__(self, title, parent): 22 | super().__init__(title, parent) 23 | 24 | self.setAcceptDrops(True) 25 | 26 | def dragEnterEvent(self, e): 27 | 28 | if e.mimeData().hasFormat('text/plain'): 29 | e.accept() 30 | else: 31 | e.ignore() 32 | 33 | def dropEvent(self, e): 34 | 35 | self.setText(e.mimeData().text()) 36 | 37 | 38 | class Example(QWidget): 39 | 40 | def __init__(self): 41 | super().__init__() 42 | 43 | self.initUI() 44 | 45 | def initUI(self): 46 | 47 | edit = QLineEdit('', self) 48 | edit.setDragEnabled(True) 49 | edit.move(30, 65) 50 | 51 | button = Button("Button", self) 52 | button.move(190, 65) 53 | 54 | self.setWindowTitle('Simple drag and drop') 55 | self.setGeometry(300, 300, 300, 150) 56 | 57 | 58 | def main(): 59 | 60 | app = QApplication(sys.argv) 61 | ex = Example() 62 | ex.show() 63 | app.exec_() 64 | 65 | 66 | if __name__ == '__main__': 67 | main() 68 | -------------------------------------------------------------------------------- /menustoolbars/main_window.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This program creates a skeleton of 7 | a classic GUI application with a menubar, 8 | toolbar, statusbar, and a central widget. 9 | 10 | Author: Jan Bodnar 11 | Website: zetcode.com 12 | """ 13 | 14 | import sys 15 | from PyQt5.QtWidgets import QMainWindow, QTextEdit, QAction, QApplication 16 | from PyQt5.QtGui import QIcon 17 | 18 | 19 | class Example(QMainWindow): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | 27 | def initUI(self): 28 | 29 | textEdit = QTextEdit() 30 | self.setCentralWidget(textEdit) 31 | 32 | exitAct = QAction(QIcon('exit24.png'), 'Exit', self) 33 | exitAct.setShortcut('Ctrl+Q') 34 | exitAct.setStatusTip('Exit application') 35 | exitAct.triggered.connect(self.close) 36 | 37 | self.statusBar() 38 | 39 | menubar = self.menuBar() 40 | fileMenu = menubar.addMenu('&File') 41 | fileMenu.addAction(exitAct) 42 | 43 | toolbar = self.addToolBar('Exit') 44 | toolbar.addAction(exitAct) 45 | 46 | self.setGeometry(300, 300, 350, 250) 47 | self.setWindowTitle('Main window') 48 | self.show() 49 | 50 | 51 | def main(): 52 | app = QApplication(sys.argv) 53 | ex = Example() 54 | sys.exit(app.exec_()) 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /dialogs/font_dialog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we select a font name 7 | and change the font of a label. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QPushButton, 14 | QSizePolicy, QLabel, QFontDialog, QApplication) 15 | import sys 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | vbox = QVBoxLayout() 27 | 28 | btn = QPushButton('Dialog', self) 29 | btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) 30 | btn.move(20, 20) 31 | 32 | vbox.addWidget(btn) 33 | 34 | btn.clicked.connect(self.showDialog) 35 | 36 | self.lbl = QLabel('Knowledge only matters', self) 37 | self.lbl.move(130, 20) 38 | 39 | vbox.addWidget(self.lbl) 40 | self.setLayout(vbox) 41 | 42 | self.setGeometry(300, 300, 450, 350) 43 | self.setWindowTitle('Font dialog') 44 | self.show() 45 | 46 | def showDialog(self): 47 | 48 | font, ok = QFontDialog.getFont() 49 | if ok: 50 | self.lbl.setFont(font) 51 | 52 | 53 | def main(): 54 | app = QApplication(sys.argv) 55 | ex = Example() 56 | sys.exit(app.exec_()) 57 | 58 | 59 | if __name__ == '__main__': 60 | main() 61 | -------------------------------------------------------------------------------- /layout/review.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we create a bit 7 | more complicated window layout using 8 | the QGridLayout manager. 9 | 10 | Author: Jan Bodnar 11 | Website: zetcode.com 12 | """ 13 | 14 | import sys 15 | from PyQt5.QtWidgets import (QWidget, QLabel, QLineEdit, 16 | QTextEdit, QGridLayout, QApplication) 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | def initUI(self): 27 | title = QLabel('Title') 28 | author = QLabel('Author') 29 | review = QLabel('Review') 30 | 31 | titleEdit = QLineEdit() 32 | authorEdit = QLineEdit() 33 | reviewEdit = QTextEdit() 34 | 35 | grid = QGridLayout() 36 | grid.setSpacing(10) 37 | 38 | grid.addWidget(title, 1, 0) 39 | grid.addWidget(titleEdit, 1, 1) 40 | 41 | grid.addWidget(author, 2, 0) 42 | grid.addWidget(authorEdit, 2, 1) 43 | 44 | grid.addWidget(review, 3, 0) 45 | grid.addWidget(reviewEdit, 3, 1, 5, 1) 46 | 47 | self.setLayout(grid) 48 | 49 | self.setGeometry(300, 300, 350, 300) 50 | self.setWindowTitle('Review') 51 | self.show() 52 | 53 | 54 | def main(): 55 | app = QApplication(sys.argv) 56 | ex = Example() 57 | sys.exit(app.exec_()) 58 | 59 | 60 | if __name__ == '__main__': 61 | main() 62 | -------------------------------------------------------------------------------- /widgets2/spitter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This example shows 7 | how to use QSplitter widget. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | 15 | from PyQt5.QtCore import Qt 16 | from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QFrame, 17 | QSplitter, QApplication) 18 | 19 | 20 | class Example(QWidget): 21 | 22 | def __init__(self): 23 | super().__init__() 24 | 25 | self.initUI() 26 | 27 | def initUI(self): 28 | 29 | hbox = QHBoxLayout(self) 30 | 31 | topleft = QFrame(self) 32 | topleft.setFrameShape(QFrame.StyledPanel) 33 | 34 | topright = QFrame(self) 35 | topright.setFrameShape(QFrame.StyledPanel) 36 | 37 | bottom = QFrame(self) 38 | bottom.setFrameShape(QFrame.StyledPanel) 39 | 40 | splitter1 = QSplitter(Qt.Horizontal) 41 | splitter1.addWidget(topleft) 42 | splitter1.addWidget(topright) 43 | 44 | splitter2 = QSplitter(Qt.Vertical) 45 | splitter2.addWidget(splitter1) 46 | splitter2.addWidget(bottom) 47 | 48 | hbox.addWidget(splitter2) 49 | self.setLayout(hbox) 50 | 51 | self.setGeometry(300, 300, 450, 400) 52 | self.setWindowTitle('QSplitter') 53 | self.show() 54 | 55 | 56 | def main(): 57 | app = QApplication(sys.argv) 58 | ex = Example() 59 | sys.exit(app.exec_()) 60 | 61 | 62 | if __name__ == '__main__': 63 | main() 64 | -------------------------------------------------------------------------------- /dialogs/color_dialog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we select a color value 7 | from the QColorDialog and change the background 8 | color of a QFrame widget. 9 | 10 | Author: Jan Bodnar 11 | Website: zetcode.com 12 | """ 13 | 14 | from PyQt5.QtWidgets import (QWidget, QPushButton, QFrame, 15 | QColorDialog, QApplication) 16 | from PyQt5.QtGui import QColor 17 | import sys 18 | 19 | 20 | class Example(QWidget): 21 | 22 | def __init__(self): 23 | super().__init__() 24 | 25 | self.initUI() 26 | 27 | def initUI(self): 28 | col = QColor(0, 0, 0) 29 | 30 | self.btn = QPushButton('Dialog', self) 31 | self.btn.move(20, 20) 32 | 33 | self.btn.clicked.connect(self.showDialog) 34 | 35 | self.frm = QFrame(self) 36 | self.frm.setStyleSheet("QWidget { background-color: %s }" 37 | % col.name()) 38 | self.frm.setGeometry(130, 22, 200, 200) 39 | 40 | self.setGeometry(300, 300, 450, 350) 41 | self.setWindowTitle('Color dialog') 42 | self.show() 43 | 44 | def showDialog(self): 45 | col = QColorDialog.getColor() 46 | 47 | if col.isValid(): 48 | self.frm.setStyleSheet('QWidget { background-color: %s }' 49 | % col.name()) 50 | 51 | 52 | def main(): 53 | app = QApplication(sys.argv) 54 | ex = Example() 55 | sys.exit(app.exec_()) 56 | 57 | 58 | if __name__ == '__main__': 59 | main() 60 | -------------------------------------------------------------------------------- /widgets/slider.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This example shows a QSlider widget. 7 | 8 | Author: Jan Bodnar 9 | Website: zetcode.com 10 | """ 11 | 12 | from PyQt5.QtWidgets import (QWidget, QSlider, 13 | QLabel, QApplication) 14 | from PyQt5.QtCore import Qt 15 | from PyQt5.QtGui import QPixmap 16 | import sys 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | def initUI(self): 27 | 28 | sld = QSlider(Qt.Horizontal, self) 29 | sld.setFocusPolicy(Qt.NoFocus) 30 | sld.setGeometry(30, 40, 200, 30) 31 | sld.valueChanged[int].connect(self.changeValue) 32 | 33 | self.label = QLabel(self) 34 | self.label.setPixmap(QPixmap('mute.png')) 35 | self.label.setGeometry(250, 40, 80, 30) 36 | 37 | self.setGeometry(300, 300, 350, 250) 38 | self.setWindowTitle('QSlider') 39 | self.show() 40 | 41 | def changeValue(self, value): 42 | 43 | if value == 0: 44 | 45 | self.label.setPixmap(QPixmap('mute.png')) 46 | elif 0 < value <= 30: 47 | 48 | self.label.setPixmap(QPixmap('min.png')) 49 | elif 30 < value < 80: 50 | 51 | self.label.setPixmap(QPixmap('med.png')) 52 | else: 53 | 54 | self.label.setPixmap(QPixmap('max.png')) 55 | 56 | 57 | def main(): 58 | app = QApplication(sys.argv) 59 | ex = Example() 60 | sys.exit(app.exec_()) 61 | 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /widgets/progressbar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This example shows a QProgressBar widget. 7 | 8 | Author: Jan Bodnar 9 | Website: zetcode.com 10 | """ 11 | 12 | from PyQt5.QtWidgets import (QWidget, QProgressBar, 13 | QPushButton, QApplication) 14 | from PyQt5.QtCore import QBasicTimer 15 | import sys 16 | 17 | 18 | class Example(QWidget): 19 | 20 | def __init__(self): 21 | super().__init__() 22 | 23 | self.initUI() 24 | 25 | def initUI(self): 26 | 27 | self.pbar = QProgressBar(self) 28 | self.pbar.setGeometry(30, 40, 200, 25) 29 | 30 | self.btn = QPushButton('Start', self) 31 | self.btn.move(40, 80) 32 | self.btn.clicked.connect(self.doAction) 33 | 34 | self.timer = QBasicTimer() 35 | self.step = 0 36 | 37 | self.setGeometry(300, 300, 280, 170) 38 | self.setWindowTitle('QProgressBar') 39 | self.show() 40 | 41 | def timerEvent(self, e): 42 | 43 | if self.step >= 100: 44 | self.timer.stop() 45 | self.btn.setText('Finished') 46 | return 47 | 48 | self.step = self.step + 1 49 | self.pbar.setValue(self.step) 50 | 51 | def doAction(self): 52 | 53 | if self.timer.isActive(): 54 | self.timer.stop() 55 | self.btn.setText('Start') 56 | else: 57 | self.timer.start(100, self) 58 | self.btn.setText('Stop') 59 | 60 | 61 | def main(): 62 | app = QApplication(sys.argv) 63 | ex = Example() 64 | sys.exit(app.exec_()) 65 | 66 | 67 | if __name__ == '__main__': 68 | main() 69 | -------------------------------------------------------------------------------- /dialogs/file_dialog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we select a file with a 7 | QFileDialog and display its contents 8 | in a QTextEdit. 9 | 10 | Author: Jan Bodnar 11 | Website: zetcode.com 12 | """ 13 | 14 | import sys 15 | from pathlib import Path 16 | 17 | from PyQt5.QtGui import QIcon 18 | from PyQt5.QtWidgets import (QMainWindow, QTextEdit, 19 | QAction, QFileDialog, QApplication) 20 | 21 | 22 | class Example(QMainWindow): 23 | 24 | def __init__(self): 25 | super().__init__() 26 | 27 | self.initUI() 28 | 29 | def initUI(self): 30 | self.textEdit = QTextEdit() 31 | self.setCentralWidget(self.textEdit) 32 | self.statusBar() 33 | 34 | openFile = QAction(QIcon('open.png'), 'Open', self) 35 | openFile.setShortcut('Ctrl+O') 36 | openFile.setStatusTip('Open new File') 37 | openFile.triggered.connect(self.showDialog) 38 | 39 | menubar = self.menuBar() 40 | fileMenu = menubar.addMenu('&File') 41 | fileMenu.addAction(openFile) 42 | 43 | self.setGeometry(300, 300, 550, 450) 44 | self.setWindowTitle('File dialog') 45 | self.show() 46 | 47 | def showDialog(self): 48 | 49 | home_dir = str(Path.home()) 50 | 51 | fname = QFileDialog.getOpenFileName(self, 'Open file', home_dir) 52 | 53 | if fname[0]: 54 | f = open(fname[0], 'r') 55 | 56 | with f: 57 | data = f.read() 58 | self.textEdit.setText(data) 59 | 60 | 61 | def main(): 62 | app = QApplication(sys.argv) 63 | ex = Example() 64 | sys.exit(app.exec_()) 65 | 66 | 67 | if __name__ == '__main__': 68 | main() 69 | -------------------------------------------------------------------------------- /painting/pens.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example we draw 6 lines using 7 | different pen styles. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | from PyQt5.QtWidgets import QWidget, QApplication 14 | from PyQt5.QtGui import QPainter, QPen 15 | from PyQt5.QtCore import Qt 16 | import sys 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | def initUI(self): 27 | self.setGeometry(300, 300, 280, 270) 28 | self.setWindowTitle('Pen styles') 29 | self.show() 30 | 31 | def paintEvent(self, e): 32 | qp = QPainter() 33 | qp.begin(self) 34 | self.drawLines(qp) 35 | qp.end() 36 | 37 | def drawLines(self, qp): 38 | pen = QPen(Qt.black, 2, Qt.SolidLine) 39 | 40 | qp.setPen(pen) 41 | qp.drawLine(20, 40, 250, 40) 42 | 43 | pen.setStyle(Qt.DashLine) 44 | qp.setPen(pen) 45 | qp.drawLine(20, 80, 250, 80) 46 | 47 | pen.setStyle(Qt.DashDotLine) 48 | qp.setPen(pen) 49 | qp.drawLine(20, 120, 250, 120) 50 | 51 | pen.setStyle(Qt.DotLine) 52 | qp.setPen(pen) 53 | qp.drawLine(20, 160, 250, 160) 54 | 55 | pen.setStyle(Qt.DashDotDotLine) 56 | qp.setPen(pen) 57 | qp.drawLine(20, 200, 250, 200) 58 | 59 | pen.setStyle(Qt.CustomDashLine) 60 | pen.setDashPattern([1, 4, 5, 4]) 61 | qp.setPen(pen) 62 | qp.drawLine(20, 240, 250, 240) 63 | 64 | 65 | def main(): 66 | app = QApplication(sys.argv) 67 | ex = Example() 68 | sys.exit(app.exec_()) 69 | 70 | 71 | if __name__ == '__main__': 72 | main() 73 | -------------------------------------------------------------------------------- /dragdrop/drag_button.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this program, we can press on a button with a left mouse 7 | click or drag and drop the button with the right mouse click. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | import sys 14 | 15 | from PyQt5.QtCore import Qt, QMimeData 16 | from PyQt5.QtGui import QDrag 17 | from PyQt5.QtWidgets import QPushButton, QWidget, QApplication 18 | 19 | 20 | class Button(QPushButton): 21 | 22 | def __init__(self, title, parent): 23 | super().__init__(title, parent) 24 | 25 | def mouseMoveEvent(self, e): 26 | 27 | if e.buttons() != Qt.RightButton: 28 | return 29 | 30 | mimeData = QMimeData() 31 | 32 | drag = QDrag(self) 33 | drag.setMimeData(mimeData) 34 | drag.setHotSpot(e.pos() - self.rect().topLeft()) 35 | 36 | dropAction = drag.exec_(Qt.MoveAction) 37 | 38 | def mousePressEvent(self, e): 39 | 40 | super().mousePressEvent(e) 41 | 42 | if e.button() == Qt.LeftButton: 43 | print('press') 44 | 45 | 46 | class Example(QWidget): 47 | 48 | def __init__(self): 49 | super().__init__() 50 | 51 | self.initUI() 52 | 53 | def initUI(self): 54 | 55 | self.setAcceptDrops(True) 56 | 57 | self.button = Button('Button', self) 58 | self.button.move(100, 65) 59 | 60 | self.setWindowTitle('Click or Move') 61 | self.setGeometry(300, 300, 550, 450) 62 | 63 | def dragEnterEvent(self, e): 64 | e.accept() 65 | 66 | def dropEvent(self, e): 67 | position = e.pos() 68 | self.button.move(position) 69 | 70 | e.setDropAction(Qt.MoveAction) 71 | e.accept() 72 | 73 | 74 | def main(): 75 | 76 | app = QApplication(sys.argv) 77 | ex = Example() 78 | ex.show() 79 | app.exec_() 80 | 81 | 82 | if __name__ == '__main__': 83 | main() 84 | -------------------------------------------------------------------------------- /painting/brushes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This example draws nine rectangles in different 7 | brush styles. 8 | 9 | Author: Jan Bodnar 10 | Website: zetcode.com 11 | """ 12 | 13 | from PyQt5.QtWidgets import QWidget, QApplication 14 | from PyQt5.QtGui import QPainter, QBrush 15 | from PyQt5.QtCore import Qt 16 | import sys 17 | 18 | 19 | class Example(QWidget): 20 | 21 | def __init__(self): 22 | super().__init__() 23 | 24 | self.initUI() 25 | 26 | def initUI(self): 27 | self.setGeometry(300, 300, 355, 280) 28 | self.setWindowTitle('Brushes') 29 | self.show() 30 | 31 | def paintEvent(self, e): 32 | qp = QPainter() 33 | qp.begin(self) 34 | self.drawBrushes(qp) 35 | qp.end() 36 | 37 | def drawBrushes(self, qp): 38 | brush = QBrush(Qt.SolidPattern) 39 | qp.setBrush(brush) 40 | qp.drawRect(10, 15, 90, 60) 41 | 42 | brush.setStyle(Qt.Dense1Pattern) 43 | qp.setBrush(brush) 44 | qp.drawRect(130, 15, 90, 60) 45 | 46 | brush.setStyle(Qt.Dense2Pattern) 47 | qp.setBrush(brush) 48 | qp.drawRect(250, 15, 90, 60) 49 | 50 | brush.setStyle(Qt.DiagCrossPattern) 51 | qp.setBrush(brush) 52 | qp.drawRect(10, 105, 90, 60) 53 | 54 | brush.setStyle(Qt.Dense5Pattern) 55 | qp.setBrush(brush) 56 | qp.drawRect(130, 105, 90, 60) 57 | 58 | brush.setStyle(Qt.Dense6Pattern) 59 | qp.setBrush(brush) 60 | qp.drawRect(250, 105, 90, 60) 61 | 62 | brush.setStyle(Qt.HorPattern) 63 | qp.setBrush(brush) 64 | qp.drawRect(10, 195, 90, 60) 65 | 66 | brush.setStyle(Qt.VerPattern) 67 | qp.setBrush(brush) 68 | qp.drawRect(130, 195, 90, 60) 69 | 70 | brush.setStyle(Qt.BDiagPattern) 71 | qp.setBrush(brush) 72 | qp.drawRect(250, 195, 90, 60) 73 | 74 | 75 | def main(): 76 | app = QApplication(sys.argv) 77 | ex = Example() 78 | sys.exit(app.exec_()) 79 | 80 | 81 | if __name__ == '__main__': 82 | main() 83 | -------------------------------------------------------------------------------- /widgets/toggle_button.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we create three toggle buttons. 7 | They will control the background color of a 8 | QFrame. 9 | 10 | Author: Jan Bodnar 11 | Website: zetcode.com 12 | """ 13 | 14 | from PyQt5.QtWidgets import (QWidget, QPushButton, 15 | QFrame, QApplication) 16 | from PyQt5.QtGui import QColor 17 | import sys 18 | 19 | 20 | class Example(QWidget): 21 | 22 | def __init__(self): 23 | super().__init__() 24 | 25 | self.initUI() 26 | 27 | def initUI(self): 28 | 29 | self.col = QColor(0, 0, 0) 30 | 31 | redb = QPushButton('Red', self) 32 | redb.setCheckable(True) 33 | redb.move(10, 10) 34 | 35 | redb.clicked[bool].connect(self.setColor) 36 | 37 | greenb = QPushButton('Green', self) 38 | greenb.setCheckable(True) 39 | greenb.move(10, 60) 40 | 41 | greenb.clicked[bool].connect(self.setColor) 42 | 43 | blueb = QPushButton('Blue', self) 44 | blueb.setCheckable(True) 45 | blueb.move(10, 110) 46 | 47 | blueb.clicked[bool].connect(self.setColor) 48 | 49 | self.square = QFrame(self) 50 | self.square.setGeometry(150, 20, 100, 100) 51 | self.square.setStyleSheet("QWidget { background-color: %s }" % 52 | self.col.name()) 53 | 54 | self.setGeometry(300, 300, 300, 250) 55 | self.setWindowTitle('Toggle button') 56 | self.show() 57 | 58 | def setColor(self, pressed): 59 | 60 | source = self.sender() 61 | 62 | if pressed: 63 | val = 255 64 | else: 65 | val = 0 66 | 67 | if source.text() == "Red": 68 | self.col.setRed(val) 69 | elif source.text() == "Green": 70 | self.col.setGreen(val) 71 | else: 72 | self.col.setBlue(val) 73 | 74 | self.square.setStyleSheet("QFrame { background-color: %s }" % 75 | self.col.name()) 76 | 77 | 78 | def main(): 79 | app = QApplication(sys.argv) 80 | ex = Example() 81 | sys.exit(app.exec_()) 82 | 83 | 84 | if __name__ == '__main__': 85 | main() 86 | -------------------------------------------------------------------------------- /customwidget/custom_widget.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | In this example, we create a custom widget. 7 | 8 | Author: Jan Bodnar 9 | Website: zetcode.com 10 | """ 11 | 12 | from PyQt5.QtWidgets import (QWidget, QSlider, QApplication, 13 | QHBoxLayout, QVBoxLayout) 14 | from PyQt5.QtCore import QObject, Qt, pyqtSignal 15 | from PyQt5.QtGui import QPainter, QFont, QColor, QPen 16 | import sys 17 | 18 | 19 | class Communicate(QObject): 20 | updateBW = pyqtSignal(int) 21 | 22 | 23 | class BurningWidget(QWidget): 24 | 25 | def __init__(self): 26 | super().__init__() 27 | 28 | self.initUI() 29 | 30 | def initUI(self): 31 | 32 | self.setMinimumSize(1, 30) 33 | self.value = 75 34 | self.num = [75, 150, 225, 300, 375, 450, 525, 600, 675] 35 | 36 | def setValue(self, value): 37 | 38 | self.value = value 39 | 40 | def paintEvent(self, e): 41 | 42 | qp = QPainter() 43 | qp.begin(self) 44 | self.drawWidget(qp) 45 | qp.end() 46 | 47 | def drawWidget(self, qp): 48 | 49 | MAX_CAPACITY = 700 50 | OVER_CAPACITY = 750 51 | 52 | font = QFont('Serif', 7, QFont.Light) 53 | qp.setFont(font) 54 | 55 | size = self.size() 56 | w = size.width() 57 | h = size.height() 58 | 59 | step = int(round(w / 10)) 60 | 61 | till = int(((w / OVER_CAPACITY) * self.value)) 62 | full = int(((w / OVER_CAPACITY) * MAX_CAPACITY)) 63 | 64 | if self.value >= MAX_CAPACITY: 65 | 66 | qp.setPen(QColor(255, 255, 255)) 67 | qp.setBrush(QColor(255, 255, 184)) 68 | qp.drawRect(0, 0, full, h) 69 | qp.setPen(QColor(255, 175, 175)) 70 | qp.setBrush(QColor(255, 175, 175)) 71 | qp.drawRect(full, 0, till - full, h) 72 | 73 | else: 74 | 75 | qp.setPen(QColor(255, 255, 255)) 76 | qp.setBrush(QColor(255, 255, 184)) 77 | qp.drawRect(0, 0, till, h) 78 | 79 | pen = QPen(QColor(20, 20, 20), 1, 80 | Qt.SolidLine) 81 | 82 | qp.setPen(pen) 83 | qp.setBrush(Qt.NoBrush) 84 | qp.drawRect(0, 0, w - 1, h - 1) 85 | 86 | j = 0 87 | 88 | for i in range(step, 10 * step, step): 89 | 90 | qp.drawLine(i, 0, i, 5) 91 | metrics = qp.fontMetrics() 92 | fw = metrics.width(str(self.num[j])) 93 | 94 | x, y = int(i - fw/2), int(h / 2) 95 | qp.drawText(x, y, str(self.num[j])) 96 | j = j + 1 97 | 98 | 99 | class Example(QWidget): 100 | 101 | def __init__(self): 102 | super().__init__() 103 | 104 | self.initUI() 105 | 106 | def initUI(self): 107 | 108 | OVER_CAPACITY = 750 109 | 110 | sld = QSlider(Qt.Horizontal, self) 111 | sld.setFocusPolicy(Qt.NoFocus) 112 | sld.setRange(1, OVER_CAPACITY) 113 | sld.setValue(75) 114 | sld.setGeometry(30, 40, 150, 30) 115 | 116 | self.c = Communicate() 117 | self.wid = BurningWidget() 118 | self.c.updateBW[int].connect(self.wid.setValue) 119 | 120 | sld.valueChanged[int].connect(self.changeValue) 121 | hbox = QHBoxLayout() 122 | hbox.addWidget(self.wid) 123 | vbox = QVBoxLayout() 124 | vbox.addStretch(1) 125 | vbox.addLayout(hbox) 126 | self.setLayout(vbox) 127 | 128 | self.setGeometry(300, 300, 390, 210) 129 | self.setWindowTitle('Burning widget') 130 | self.show() 131 | 132 | def changeValue(self, value): 133 | self.c.updateBW.emit(value) 134 | self.wid.repaint() 135 | 136 | 137 | def main(): 138 | app = QApplication(sys.argv) 139 | ex = Example() 140 | sys.exit(app.exec_()) 141 | 142 | 143 | if __name__ == '__main__': 144 | main() 145 | -------------------------------------------------------------------------------- /tetris/tetris.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | """ 4 | ZetCode PyQt5 tutorial 5 | 6 | This is a Tetris game clone. 7 | 8 | Author: Jan Bodnar 9 | Website: zetcode.com 10 | """ 11 | 12 | import random 13 | import sys 14 | 15 | from PyQt5.QtCore import Qt, QBasicTimer, pyqtSignal 16 | from PyQt5.QtGui import QPainter, QColor 17 | from PyQt5.QtWidgets import QMainWindow, QFrame, QDesktopWidget, QApplication 18 | 19 | 20 | class Tetris(QMainWindow): 21 | 22 | def __init__(self): 23 | super().__init__() 24 | 25 | self.initUI() 26 | 27 | def initUI(self): 28 | """initiates application UI""" 29 | 30 | self.tboard = Board(self) 31 | self.setCentralWidget(self.tboard) 32 | 33 | self.statusbar = self.statusBar() 34 | self.tboard.msg2Statusbar[str].connect(self.statusbar.showMessage) 35 | 36 | self.tboard.start() 37 | 38 | self.resize(180, 380) 39 | self.center() 40 | self.setWindowTitle('Tetris') 41 | self.show() 42 | 43 | def center(self): 44 | """centers the window on the screen""" 45 | 46 | screen = QDesktopWidget().screenGeometry() 47 | size = self.geometry() 48 | self.move(int((screen.width() - size.width()) / 2), 49 | int((screen.height() - size.height()) / 2)) 50 | 51 | 52 | class Board(QFrame): 53 | msg2Statusbar = pyqtSignal(str) 54 | 55 | BoardWidth = 10 56 | BoardHeight = 22 57 | Speed = 300 58 | 59 | def __init__(self, parent): 60 | super().__init__(parent) 61 | 62 | self.initBoard() 63 | 64 | def initBoard(self): 65 | """initiates board""" 66 | 67 | self.timer = QBasicTimer() 68 | self.isWaitingAfterLine = False 69 | 70 | self.curX = 0 71 | self.curY = 0 72 | self.numLinesRemoved = 0 73 | self.board = [] 74 | 75 | self.setFocusPolicy(Qt.StrongFocus) 76 | self.isStarted = False 77 | self.isPaused = False 78 | self.clearBoard() 79 | 80 | def shapeAt(self, x, y): 81 | """determines shape at the board position""" 82 | 83 | return self.board[(y * Board.BoardWidth) + x] 84 | 85 | def setShapeAt(self, x, y, shape): 86 | """sets a shape at the board""" 87 | 88 | self.board[(y * Board.BoardWidth) + x] = shape 89 | 90 | def squareWidth(self): 91 | """returns the width of one square""" 92 | 93 | return self.contentsRect().width() // Board.BoardWidth 94 | 95 | def squareHeight(self): 96 | """returns the height of one square""" 97 | 98 | return self.contentsRect().height() // Board.BoardHeight 99 | 100 | def start(self): 101 | """starts game""" 102 | 103 | if self.isPaused: 104 | return 105 | 106 | self.isStarted = True 107 | self.isWaitingAfterLine = False 108 | self.numLinesRemoved = 0 109 | self.clearBoard() 110 | 111 | self.msg2Statusbar.emit(str(self.numLinesRemoved)) 112 | 113 | self.newPiece() 114 | self.timer.start(Board.Speed, self) 115 | 116 | def pause(self): 117 | """pauses game""" 118 | 119 | if not self.isStarted: 120 | return 121 | 122 | self.isPaused = not self.isPaused 123 | 124 | if self.isPaused: 125 | self.timer.stop() 126 | self.msg2Statusbar.emit("paused") 127 | 128 | else: 129 | self.timer.start(Board.Speed, self) 130 | self.msg2Statusbar.emit(str(self.numLinesRemoved)) 131 | 132 | self.update() 133 | 134 | def paintEvent(self, event): 135 | """paints all shapes of the game""" 136 | 137 | painter = QPainter(self) 138 | rect = self.contentsRect() 139 | 140 | boardTop = rect.bottom() - Board.BoardHeight * self.squareHeight() 141 | 142 | for i in range(Board.BoardHeight): 143 | for j in range(Board.BoardWidth): 144 | shape = self.shapeAt(j, Board.BoardHeight - i - 1) 145 | 146 | if shape != Tetrominoe.NoShape: 147 | self.drawSquare(painter, 148 | rect.left() + j * self.squareWidth(), 149 | boardTop + i * self.squareHeight(), shape) 150 | 151 | if self.curPiece.shape() != Tetrominoe.NoShape: 152 | 153 | for i in range(4): 154 | x = self.curX + self.curPiece.x(i) 155 | y = self.curY - self.curPiece.y(i) 156 | self.drawSquare(painter, rect.left() + x * self.squareWidth(), 157 | boardTop + (Board.BoardHeight - y - 1) * self.squareHeight(), 158 | self.curPiece.shape()) 159 | 160 | def keyPressEvent(self, event): 161 | """processes key press events""" 162 | 163 | if not self.isStarted or self.curPiece.shape() == Tetrominoe.NoShape: 164 | super(Board, self).keyPressEvent(event) 165 | return 166 | 167 | key = event.key() 168 | 169 | if key == Qt.Key_P: 170 | self.pause() 171 | return 172 | 173 | if self.isPaused: 174 | return 175 | 176 | elif key == Qt.Key_Left: 177 | self.tryMove(self.curPiece, self.curX - 1, self.curY) 178 | 179 | elif key == Qt.Key_Right: 180 | self.tryMove(self.curPiece, self.curX + 1, self.curY) 181 | 182 | elif key == Qt.Key_Down: 183 | self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY) 184 | 185 | elif key == Qt.Key_Up: 186 | self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY) 187 | 188 | elif key == Qt.Key_Space: 189 | self.dropDown() 190 | 191 | elif key == Qt.Key_D: 192 | self.oneLineDown() 193 | 194 | else: 195 | super(Board, self).keyPressEvent(event) 196 | 197 | def timerEvent(self, event): 198 | """handles timer event""" 199 | 200 | if event.timerId() == self.timer.timerId(): 201 | 202 | if self.isWaitingAfterLine: 203 | self.isWaitingAfterLine = False 204 | self.newPiece() 205 | else: 206 | self.oneLineDown() 207 | 208 | else: 209 | super(Board, self).timerEvent(event) 210 | 211 | def clearBoard(self): 212 | """clears shapes from the board""" 213 | 214 | for i in range(Board.BoardHeight * Board.BoardWidth): 215 | self.board.append(Tetrominoe.NoShape) 216 | 217 | def dropDown(self): 218 | """drops down a shape""" 219 | 220 | newY = self.curY 221 | 222 | while newY > 0: 223 | 224 | if not self.tryMove(self.curPiece, self.curX, newY - 1): 225 | break 226 | 227 | newY -= 1 228 | 229 | self.pieceDropped() 230 | 231 | def oneLineDown(self): 232 | """goes one line down with a shape""" 233 | 234 | if not self.tryMove(self.curPiece, self.curX, self.curY - 1): 235 | self.pieceDropped() 236 | 237 | def pieceDropped(self): 238 | """after dropping shape, remove full lines and create new shape""" 239 | 240 | for i in range(4): 241 | x = self.curX + self.curPiece.x(i) 242 | y = self.curY - self.curPiece.y(i) 243 | self.setShapeAt(x, y, self.curPiece.shape()) 244 | 245 | self.removeFullLines() 246 | 247 | if not self.isWaitingAfterLine: 248 | self.newPiece() 249 | 250 | def removeFullLines(self): 251 | """removes all full lines from the board""" 252 | 253 | numFullLines = 0 254 | rowsToRemove = [] 255 | 256 | for i in range(Board.BoardHeight): 257 | 258 | n = 0 259 | for j in range(Board.BoardWidth): 260 | if not self.shapeAt(j, i) == Tetrominoe.NoShape: 261 | n = n + 1 262 | 263 | if n == 10: 264 | rowsToRemove.append(i) 265 | 266 | rowsToRemove.reverse() 267 | 268 | for m in rowsToRemove: 269 | 270 | for k in range(m, Board.BoardHeight): 271 | for l in range(Board.BoardWidth): 272 | self.setShapeAt(l, k, self.shapeAt(l, k + 1)) 273 | 274 | numFullLines = numFullLines + len(rowsToRemove) 275 | 276 | if numFullLines > 0: 277 | self.numLinesRemoved = self.numLinesRemoved + numFullLines 278 | self.msg2Statusbar.emit(str(self.numLinesRemoved)) 279 | 280 | self.isWaitingAfterLine = True 281 | self.curPiece.setShape(Tetrominoe.NoShape) 282 | self.update() 283 | 284 | def newPiece(self): 285 | """creates a new shape""" 286 | 287 | self.curPiece = Shape() 288 | self.curPiece.setRandomShape() 289 | self.curX = Board.BoardWidth // 2 + 1 290 | self.curY = Board.BoardHeight - 1 + self.curPiece.minY() 291 | 292 | if not self.tryMove(self.curPiece, self.curX, self.curY): 293 | self.curPiece.setShape(Tetrominoe.NoShape) 294 | self.timer.stop() 295 | self.isStarted = False 296 | self.msg2Statusbar.emit("Game over") 297 | 298 | def tryMove(self, newPiece, newX, newY): 299 | """tries to move a shape""" 300 | 301 | for i in range(4): 302 | 303 | x = newX + newPiece.x(i) 304 | y = newY - newPiece.y(i) 305 | 306 | if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight: 307 | return False 308 | 309 | if self.shapeAt(x, y) != Tetrominoe.NoShape: 310 | return False 311 | 312 | self.curPiece = newPiece 313 | self.curX = newX 314 | self.curY = newY 315 | self.update() 316 | 317 | return True 318 | 319 | def drawSquare(self, painter, x, y, shape): 320 | """draws a square of a shape""" 321 | 322 | colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC, 323 | 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00] 324 | 325 | color = QColor(colorTable[shape]) 326 | painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, 327 | self.squareHeight() - 2, color) 328 | 329 | painter.setPen(color.lighter()) 330 | painter.drawLine(x, y + self.squareHeight() - 1, x, y) 331 | painter.drawLine(x, y, x + self.squareWidth() - 1, y) 332 | 333 | painter.setPen(color.darker()) 334 | painter.drawLine(x + 1, y + self.squareHeight() - 1, 335 | x + self.squareWidth() - 1, y + self.squareHeight() - 1) 336 | painter.drawLine(x + self.squareWidth() - 1, 337 | y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1) 338 | 339 | 340 | class Tetrominoe(object): 341 | NoShape = 0 342 | ZShape = 1 343 | SShape = 2 344 | LineShape = 3 345 | TShape = 4 346 | SquareShape = 5 347 | LShape = 6 348 | MirroredLShape = 7 349 | 350 | 351 | class Shape(object): 352 | coordsTable = ( 353 | ((0, 0), (0, 0), (0, 0), (0, 0)), 354 | ((0, -1), (0, 0), (-1, 0), (-1, 1)), 355 | ((0, -1), (0, 0), (1, 0), (1, 1)), 356 | ((0, -1), (0, 0), (0, 1), (0, 2)), 357 | ((-1, 0), (0, 0), (1, 0), (0, 1)), 358 | ((0, 0), (1, 0), (0, 1), (1, 1)), 359 | ((-1, -1), (0, -1), (0, 0), (0, 1)), 360 | ((1, -1), (0, -1), (0, 0), (0, 1)) 361 | ) 362 | 363 | def __init__(self): 364 | 365 | self.coords = [[0, 0] for i in range(4)] 366 | self.pieceShape = Tetrominoe.NoShape 367 | 368 | self.setShape(Tetrominoe.NoShape) 369 | 370 | def shape(self): 371 | """returns shape""" 372 | 373 | return self.pieceShape 374 | 375 | def setShape(self, shape): 376 | """sets a shape""" 377 | 378 | table = Shape.coordsTable[shape] 379 | 380 | for i in range(4): 381 | for j in range(2): 382 | self.coords[i][j] = table[i][j] 383 | 384 | self.pieceShape = shape 385 | 386 | def setRandomShape(self): 387 | """chooses a random shape""" 388 | 389 | self.setShape(random.randint(1, 7)) 390 | 391 | def x(self, index): 392 | """returns x coordinate""" 393 | 394 | return self.coords[index][0] 395 | 396 | def y(self, index): 397 | """returns y coordinate""" 398 | 399 | return self.coords[index][1] 400 | 401 | def setX(self, index, x): 402 | """sets x coordinate""" 403 | 404 | self.coords[index][0] = x 405 | 406 | def setY(self, index, y): 407 | """sets y coordinate""" 408 | 409 | self.coords[index][1] = y 410 | 411 | def minX(self): 412 | """returns min x value""" 413 | 414 | m = self.coords[0][0] 415 | for i in range(4): 416 | m = min(m, self.coords[i][0]) 417 | 418 | return m 419 | 420 | def maxX(self): 421 | """returns max x value""" 422 | 423 | m = self.coords[0][0] 424 | for i in range(4): 425 | m = max(m, self.coords[i][0]) 426 | 427 | return m 428 | 429 | def minY(self): 430 | """returns min y value""" 431 | 432 | m = self.coords[0][1] 433 | for i in range(4): 434 | m = min(m, self.coords[i][1]) 435 | 436 | return m 437 | 438 | def maxY(self): 439 | """returns max y value""" 440 | 441 | m = self.coords[0][1] 442 | for i in range(4): 443 | m = max(m, self.coords[i][1]) 444 | 445 | return m 446 | 447 | def rotateLeft(self): 448 | """rotates shape to the left""" 449 | 450 | if self.pieceShape == Tetrominoe.SquareShape: 451 | return self 452 | 453 | result = Shape() 454 | result.pieceShape = self.pieceShape 455 | 456 | for i in range(4): 457 | result.setX(i, self.y(i)) 458 | result.setY(i, -self.x(i)) 459 | 460 | return result 461 | 462 | def rotateRight(self): 463 | """rotates shape to the right""" 464 | 465 | if self.pieceShape == Tetrominoe.SquareShape: 466 | return self 467 | 468 | result = Shape() 469 | result.pieceShape = self.pieceShape 470 | 471 | for i in range(4): 472 | result.setX(i, -self.y(i)) 473 | result.setY(i, self.x(i)) 474 | 475 | return result 476 | 477 | 478 | def main(): 479 | 480 | app = QApplication([]) 481 | tetris = Tetris() 482 | sys.exit(app.exec_()) 483 | 484 | 485 | if __name__ == '__main__': 486 | main() 487 | 488 | --------------------------------------------------------------------------------