# <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>" \
"⁣" \
"<img src=icon.svg>" \
"</center>" \
"<p>Version 31.4.159.265358<br/>" \
"Copyright © Company Inc.</p>"
QMessageBox.about(window, "About Text Editor", text)
about_action.triggered.connect(show_about_dialog)
window.show()
app.exec()
```