# <center><i class="fa fa-edit"></i> Smart Dispenser: Understanding PyQt </center> ###### tags: `Internship` :::info **Goal:** - [x] Understanding PyQt Structure **Resources:** [PyQt](https://hackmd.io/Ibk_VuuWRXOjkION4wk3tg) [目前做到現在的程式](https://drive.google.com/drive/folders/1QNJJxxug1Njb9ATe-BdzcZKZZ1PGI2Sd?usp=sharing) ::: ### PyQt QTreeview ``` from os.path import expanduser from PyQt6.QtWidgets import * home_directory = expanduser('~') app = QApplication([]) model = QDirModel() view = QTreeView() view.setModel(model) view.setRootIndex(model.index(home_directory)) view.show() app.exec() ``` ### PyQt Database **Main** ``` from os.path import exists from PyQt6.QtWidgets import * from PyQt6.QtSql import * import sys if not exists("projects.db"): print("File projects.db does not exist. Please run initdb.py.") sys.exit() app = QApplication([]) db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName("projects.db") db.open() model = QSqlTableModel(None, db) model.setTable("projects") model.select() view = QTableView() view.setModel(model) view.show() app.exec() ``` **Database** ``` import sqlite3 connection = sqlite3.connect("projects.db") cursor = connection.cursor() cursor.execute(""" CREATE TABLE projects (url TEXT, descr TEXT, income INTEGER) """) cursor.execute("""INSERT INTO projects VALUES ('giraffes.io', 'Uber, but with giraffes', 1900), ('dronesweaters.com', 'Clothes for cold drones', 3000), ('hummingpro.io', 'Online humming courses', 120000) """) connection.commit() ``` ### PyQt QPainter ``` from PyQt6.QtWidgets import * from PyQt6.QtGui import * from PyQt6.QtCore import * from PyQt6.QtMultimedia import QSound class PlainTextEdit(QPlainTextEdit): def __init__(self): super().__init__() self._holes = [] self._bullet = QPixmap("bullet.png") size = self._bullet.size() self._offset = QPoint(size.width() / 2, size.height() / 2) def mousePressEvent(self, e): self._holes.append(e.pos()) super().mousePressEvent(e) self.viewport().update() QSound.play("shot.wav") def paintEvent(self, e): super().paintEvent(e) painter = QPainter(self.viewport()) for hole in self._holes: painter.drawPixmap(hole - self._offset, self._bullet) app = QApplication([]) text = PlainTextEdit() text.setPlainText("Click with the mouse below to shoot ;-)") # The rest of the code is as for the normal version of the text editor. class MainWindow(QMainWindow): def closeEvent(self, e): if not text.document().isModified(): return answer = QMessageBox.question( window, None, "You have unsaved changes. Save before closing?", QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel ) if answer & QMessageBox.Save: save() elif answer & QMessageBox.Cancel: e.ignore() app.setApplicationName("Text Editor") window = MainWindow() window.setCentralWidget(text) file_path = None menu = window.menuBar().addMenu("&File") open_action = QAction("&Open") def open_file(): global file_path path = QFileDialog.getOpenFileName(window, "Open")[0] if path: text.setPlainText(open(path).read()) file_path = path open_action.triggered.connect(open_file) open_action.setShortcut(QKeySequence.Open) menu.addAction(open_action) save_action = QAction("&Save") def save(): if file_path is None: save_as() else: with open(file_path, "w") as f: f.write(text.toPlainText()) text.document().setModified(False) save_action.triggered.connect(save) save_action.setShortcut(QKeySequence.Save) menu.addAction(save_action) save_as_action = QAction("Save &As...") def save_as(): global file_path path = QFileDialog.getSaveFileName(window, "Save As")[0] if path: file_path = path save() save_as_action.triggered.connect(save_as) menu.addAction(save_as_action) close = QAction("&Close") close.triggered.connect(window.close) menu.addAction(close) help_menu = window.menuBar().addMenu("&Help") about_action = QAction("&About") help_menu.addAction(about_action) def show_about_dialog(): text = "<center>" \ "<h1>Text Editor</h1>" \ "&#8291;" \ "<img src=icon.svg>" \ "</center>" \ "<p>Version 31.4.159.265358<br/>" \ "Copyright &copy; Company Inc.</p>" QMessageBox.about(window, "About Text Editor", text) about_action.triggered.connect(show_about_dialog) window.show() app.exec() ```