simon 1 ano atrás
pai
commit
d49dd74176
58 arquivos alterados com 433 adições e 141 exclusões
  1. 103 23
      .vscode/PythonImportHelper-v2-Completion.json
  2. 2 1
      .vscode/settings.json
  3. 2 2
      MainWindow.py
  4. 3 2
      MyApp.py
  5. 1 1
      MyApp_window.py
  6. 1 0
      basic/creating_a_window_4.py
  7. 1 0
      basic/dialogs_2a.py
  8. 1 0
      basic/dialogs_3.py
  9. 3 2
      basic/dialogs_5.py
  10. 26 9
      basic/dialogs_input_1.py
  11. 1 0
      basic/dialogs_start.py
  12. 2 1
      basic/events_1.py
  13. 2 1
      basic/events_3.py
  14. 1 0
      basic/layout_1.py
  15. 13 6
      basic/layout_10.py
  16. 1 0
      basic/layout_3.py
  17. 1 0
      basic/layout_4.py
  18. 1 0
      basic/layout_7.py
  19. 1 0
      basic/layout_8.py
  20. 1 0
      basic/layout_9.py
  21. 1 0
      basic/layout_colorwidget.py
  22. 1 0
      basic/signals_and_slots_1.py
  23. 1 0
      basic/signals_and_slots_1b.py
  24. 1 0
      basic/signals_and_slots_1c.py
  25. 1 0
      basic/signals_and_slots_1d.py
  26. 1 0
      basic/signals_and_slots_2.py
  27. 3 8
      basic/signals_and_slots_3.py
  28. 1 0
      basic/signals_and_slots_4.py
  29. 10 7
      basic/windows_1.py
  30. 8 5
      basic/windows_5.py
  31. 1 0
      basic/windows_7.py
  32. 51 0
      bitmap/stub.py
  33. BIN
      databases/Chinook_Sqlite.sqlite
  34. 1 0
      databases/tableview.py
  35. 4 3
      databases/tableview_querymodel_parameter.py
  36. 3 1
      databases/tableview_relationalmodel.py
  37. 1 0
      databases/tableview_tablemodel.py
  38. 3 1
      databases/tableview_tablemodel_filter.py
  39. 94 35
      databases/widget_mapper.py
  40. 2 1
      further/mvc_1.py
  41. 1 0
      further/mvc_2.py
  42. 2 0
      further/mvc_5.py
  43. 1 0
      load_uifile.py
  44. 1 1
      model-views/MainWindow.py
  45. 8 3
      model-views/tableview_demo.py
  46. 2 0
      model-views/tableview_numpy.py
  47. 12 8
      model-views/tableview_pandas.py
  48. 2 0
      model-views/todo_1.py
  49. 1 0
      model-views/todo_skeleton.py
  50. 23 3
      paint_app.py
  51. 1 0
      pixmap.py
  52. 7 8
      power_bar.py
  53. 6 8
      power_bar_better.py
  54. 1 0
      signal_data.py
  55. 2 0
      toolbars_and_menus.py
  56. 2 0
      widgets.py
  57. 2 0
      widgets_gridlayout.py
  58. 4 1
      widgets_stacklayout.py

Diferenças do arquivo suprimidas por serem muito extensas
+ 103 - 23
.vscode/PythonImportHelper-v2-Completion.json


+ 2 - 1
.vscode/settings.json

@@ -1,8 +1,9 @@
 {
+    "$schema": "https://json.schemastore.org/settings.json",
     "python.linting.flake8Enabled": true,
     "python.formatting.provider": "yapf",
     "python.linting.flake8Args": [
         "--max-line-length=248"
     ],
-    "python.linting.pylintEnabled": false,
+    "python.linting.pylintEnabled": false
 }

+ 2 - 2
MainWindow.py

@@ -6,11 +6,11 @@
 #
 # WARNING! All changes made in this file will be lost!
 
-
-from PyQt5 import QtCore, QtGui, QtWidgets
+from PyQt5 import QtCore, QtWidgets
 
 
 class Ui_MainWindow(object):
+
     def setupUi(self, MainWindow):
         MainWindow.setObjectName("MainWindow")
         MainWindow.resize(536, 578)

+ 3 - 2
MyApp.py

@@ -1,12 +1,13 @@
 # Only needed for access to command line arguments
 import sys
 
-from PyQt5.QtCore import *
-from PyQt5.QtWidgets import *
+from PyQt5.QtCore import Qt
+from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel
 
 
 # 自定义窗口,继承 QMainWindow
 class MainWindow(QMainWindow):
+
     def __init__(self, *args, **kwargs):
         super(MainWindow, self).__init__(*args, **kwargs)
         self.setWindowTitle("My Awesome App")  # 标题

+ 1 - 1
MyApp_window.py

@@ -4,11 +4,11 @@ import sys
 from PyQt5.QtCore import *
 from PyQt5.QtWidgets import *
 
-
 # 自定义窗口,继承 QMainWindow
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self, *args, **kwargs):
         super(MainWindow, self).__init__(*args, **kwargs)
 

+ 1 - 0
basic/creating_a_window_4.py

@@ -5,6 +5,7 @@ from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle("My App")

+ 1 - 0
basic/dialogs_2a.py

@@ -2,6 +2,7 @@ from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel
 
 
 class CustomDialog(QDialog):
+
     def __init__(self, parent=None):
         super().__init__(parent)
 

+ 1 - 0
basic/dialogs_3.py

@@ -4,6 +4,7 @@ from PyQt5.QtWidgets import QMainWindow, QPushButton, QMessageBox, QApplication
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle('My App')

+ 3 - 2
basic/dialogs_5.py

@@ -4,6 +4,7 @@ from PyQt5.QtWidgets import QMainWindow, QPushButton, QMessageBox, QApplication
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle('My App')
@@ -20,8 +21,8 @@ class MainWindow(QMainWindow):
             'Oh dear!',
             'Somthing went very wrong',
             buttons=QMessageBox.Discard
-                    | QMessageBox.NoToAll
-                    | QMessageBox.Ignore,
+            | QMessageBox.NoToAll
+            | QMessageBox.Ignore,
             defaultButton=QMessageBox.Discard,
         )
 

+ 26 - 9
basic/dialogs_input_1.py

@@ -1,14 +1,16 @@
 import sys
 from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QInputDialog, QWidget, QLineEdit
 
+
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 
         self.setWindowTitle("My App")
 
         layout = QVBoxLayout()
-    
+
         button1 = QPushButton("Integer")
         button1.clicked.connect(self.get_an_int)
         layout.addWidget(button1)
@@ -31,41 +33,56 @@ class MainWindow(QMainWindow):
 
         container = QWidget()
         container.setLayout(layout)
-        
+
         self.setCentralWidget(container)
 
     def get_an_int(self):
         title = "Enter an interger"
         label = "Please enter an integer"
-        my_int_value, ok = QInputDialog.getInt(self, title, label, value=0, min=5, max=50,step=1)
+        my_int_value, ok = QInputDialog.getInt(self,
+                                               title,
+                                               label,
+                                               value=0,
+                                               min=5,
+                                               max=50,
+                                               step=1)
         print("Result:", ok, my_int_value)
 
     def get_a_float(self):
         title = "Enter a float"
         label = "Please enter a float"
-        my_float_value, ok = QInputDialog.getDouble(self, title, label, value=0.0, min=-5.3, max=10.0, decimals=2)
+        my_float_value, ok = QInputDialog.getDouble(self,
+                                                    title,
+                                                    label,
+                                                    value=0.0,
+                                                    min=-5.3,
+                                                    max=10.0,
+                                                    decimals=2)
         print("Result:", ok, my_float_value)
 
     def get_a_string_from_a_list(self):
         title = "Select an item"
         label = "Please select an item"
         items = ["apple", "pear", "orange", "grape"]
-        initail_selection = 2 # index of orange
-        item, ok = QInputDialog.getItem(self, title, label, items, initail_selection, False)
+        initail_selection = 2  # index of orange
+        item, ok = QInputDialog.getItem(self, title, label, items,
+                                        initail_selection, False)
         print("Result:", ok, item)
 
     def get_a_str(self):
         title = "Enter a string"
         label = "Type your password"
         text = "my secret password"
-        my_str_value, ok = QInputDialog.getText(self, title, label, QLineEdit.Password, text)
+        my_str_value, ok = QInputDialog.getText(self, title, label,
+                                                QLineEdit.Password, text)
         print("Result:", ok, my_str_value)
 
     def get_a_text(self):
         title = "Enter a text"
         label = "Type your message"
         text = "Hello, World! ..."
-        my_text_value, ok = QInputDialog.getMultiLineText(self, title, label, text)
+        my_text_value, ok = QInputDialog.getMultiLineText(
+            self, title, label, text)
         print("Result:", ok, my_text_value)
 
 
@@ -75,4 +92,4 @@ if __name__ == "__main__":
     window = MainWindow()
     window.show()
 
-    app.exec_()
+    app.exec_()

+ 1 - 0
basic/dialogs_start.py

@@ -6,6 +6,7 @@ from dialogs_2a import CustomDialog
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 2 - 1
basic/events_1.py

@@ -4,6 +4,7 @@ from PyQt5.QtWidgets import QMainWindow, QLabel, QApplication
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.label = QLabel("Click in this window")
@@ -27,4 +28,4 @@ class MainWindow(QMainWindow):
 app = QApplication(sys.argv)
 window = MainWindow()
 window.show()
-sys.exit(app.exec_())
+sys.exit(app.exec_())

+ 2 - 1
basic/events_3.py

@@ -5,6 +5,7 @@ from PyQt5.QtCore import Qt, pyqtSlot
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 
@@ -22,4 +23,4 @@ class MainWindow(QMainWindow):
 app = QApplication(sys.argv)
 window = MainWindow()
 window.show()
-sys.exit(app.exec_())
+sys.exit(app.exec_())

+ 1 - 0
basic/layout_1.py

@@ -6,6 +6,7 @@ from layout_colorwidget import Color
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 13 - 6
basic/layout_10.py

@@ -1,16 +1,22 @@
 import sys
 
 from PyQt5.QtWidgets import (
-    QMainWindow, QFormLayout,
-    QLineEdit, QSpinBox,
-    QComboBox, QWidget,
-    QApplication, QLabel,
-    QAction, QToolBar,
+    QMainWindow,
+    QFormLayout,
+    QLineEdit,
+    QSpinBox,
+    QComboBox,
+    QWidget,
+    QApplication,
+    QLabel,
+    QAction,
+    QToolBar,
     QStatusBar,
 )
 
 
 class MyWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle('My App')
@@ -76,7 +82,8 @@ class MyWindow(QMainWindow):
 
     def validate(self):
         if self.data["age"] > 10 and self.data["icecream"] == "Chocolate":
-            self.error.setText("People over 10 aren't allowed chocolate ice cream")
+            self.error.setText(
+                "People over 10 aren't allowed chocolate ice cream")
             return
         if self.data["age"] > 100:
             self.error.setText("Did you send a telegram?")

+ 1 - 0
basic/layout_3.py

@@ -6,6 +6,7 @@ from layout_colorwidget import Color
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 1 - 0
basic/layout_4.py

@@ -6,6 +6,7 @@ from layout_colorwidget import Color
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 1 - 0
basic/layout_7.py

@@ -6,6 +6,7 @@ from layout_colorwidget import Color
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle("My App")

+ 1 - 0
basic/layout_8.py

@@ -6,6 +6,7 @@ from layout_colorwidget import Color
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle("My App")

+ 1 - 0
basic/layout_9.py

@@ -6,6 +6,7 @@ from layout_colorwidget import Color
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle("My App")

+ 1 - 0
basic/layout_colorwidget.py

@@ -3,6 +3,7 @@ from PyQt5.QtWidgets import QWidget
 
 
 class Color(QWidget):
+
     def __init__(self, color):
         super().__init__()
         self.setAutoFillBackground(True)

+ 1 - 0
basic/signals_and_slots_1.py

@@ -8,6 +8,7 @@ def the_button_was_clicked():
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle("My App")

+ 1 - 0
basic/signals_and_slots_1b.py

@@ -12,6 +12,7 @@ def the_button_was_toggled(is_checked):
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle("My App")

+ 1 - 0
basic/signals_and_slots_1c.py

@@ -4,6 +4,7 @@ from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 1 - 0
basic/signals_and_slots_1d.py

@@ -4,6 +4,7 @@ from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 1 - 0
basic/signals_and_slots_2.py

@@ -4,6 +4,7 @@ from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 3 - 8
basic/signals_and_slots_3.py

@@ -4,19 +4,14 @@ from random import choice
 from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
 
 window_titles = [
-    "My App",
-    "My App",
-    "Still My App",
-    "Still My App",
-    "What on earth",
-    "What on earth",
-    "This is surprising",
-    "This is surprising",
+    "My App", "My App", "Still My App", "Still My App", "What on earth",
+    "What on earth", "This is surprising", "This is surprising",
     "Something went wrong"
 ]
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 1 - 0
basic/signals_and_slots_4.py

@@ -4,6 +4,7 @@ from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel, QLineEdit, QWidge
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 10 - 7
basic/windows_1.py

@@ -1,36 +1,39 @@
-import sys 
+import sys
 from random import randint
 from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QWidget, QInputDialog, QLineEdit, QLabel
 
+
 class AnotherWindow(QWidget):
     """
     This "window" is a Qwidget. If it has no parent, it 
     will appear as a free-floating window.
     """
+
     def __init__(self):
         super().__init__()
         layout = QVBoxLayout()
-        self.label = QLabel("Another Window %d" % randint(0,100))
+        self.label = QLabel("Another Window %d" % randint(0, 100))
         layout.addWidget(self.label)
         self.setLayout(layout)
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
-        self.w = None # No external window yet
+        self.w = None  # No external window yet
 
         self.setWindowTitle("My App")
 
         layout = QVBoxLayout()
-    
+
         self.button = QPushButton("Press me for a dialog!")
         self.button.clicked.connect(self.show_new_window)
         layout.addWidget(self.button)
 
         container = QWidget()
         container.setLayout(layout)
-        
+
         self.setCentralWidget(container)
 
     def show_new_window(self, is_checked):
@@ -40,10 +43,10 @@ class MainWindow(QMainWindow):
             self.w.show()
         else:
             self.w.close()
-            self.w = None   # Discard reference, close window.
+            self.w = None  # Discard reference, close window.
 
 
 app = QApplication(sys.argv)
 window = MainWindow()
 window.show()
-app.exec_()
+app.exec_()

+ 8 - 5
basic/windows_5.py

@@ -1,21 +1,24 @@
-import sys 
+import sys
 from random import randint
 from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QWidget, QInputDialog, QLineEdit, QLabel
 
+
 class AnotherWindow(QWidget):
     """
     This "window" is a Qwidget. If it has no parent, it 
     will appear as a free-floating window.
     """
+
     def __init__(self):
         super().__init__()
         layout = QVBoxLayout()
-        self.label = QLabel("Another Window %d" % randint(0,100))
+        self.label = QLabel("Another Window %d" % randint(0, 100))
         layout.addWidget(self.label)
         self.setLayout(layout)
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.w = AnotherWindow()
@@ -23,14 +26,14 @@ class MainWindow(QMainWindow):
         self.setWindowTitle("My App")
 
         layout = QVBoxLayout()
-    
+
         self.button = QPushButton("Press me for a dialog!")
         self.button.clicked.connect(self.show_new_window)
         layout.addWidget(self.button)
 
         container = QWidget()
         container.setLayout(layout)
-        
+
         self.setCentralWidget(container)
 
     def show_new_window(self, is_checked):
@@ -43,4 +46,4 @@ class MainWindow(QMainWindow):
 app = QApplication(sys.argv)
 window = MainWindow()
 window.show()
-app.exec_()
+app.exec_()

+ 1 - 0
basic/windows_7.py

@@ -19,6 +19,7 @@ class AnotherWindow(QWidget):
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.w = AnotherWindow()

+ 51 - 0
bitmap/stub.py

@@ -0,0 +1,51 @@
+from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel
+from PyQt5.QtGui import QPixmap, QPainter, QColor, QPen
+from PyQt5.QtCore import Qt
+from random import randint, choice
+
+
+class MainWindow(QMainWindow):
+
+    def __init__(self):
+        super().__init__()
+        self.initUI()
+
+    def initUI(self):
+        self.label = QLabel()
+        canvas = QPixmap(400, 300)
+        canvas.fill(Qt.white)
+        self.label.setPixmap(canvas)
+
+        self.setCentralWidget(self.label)
+        self.draw_something()
+
+    def draw_something(self):
+        colors = [
+            "#ffd141",
+            "#376f9f",
+            "#0d1f2d",
+            "#e9ebef",
+            "#eb5160",
+        ]
+        painter = QPainter(self.label.pixmap())
+        pen = QPen()
+        pen.setWidth(3)
+        pen.setColor(QColor("red"))
+        painter.setPen(pen)
+
+        for n in range(10000):
+            pen.setColor(QColor(choice(colors)))
+            painter.setPen(pen)
+            painter.drawPoint(
+                200 + randint(-100, 100),
+                150 + randint(-100, 100),
+            )
+        painter.end()
+
+
+if __name__ == '__main__':
+    import sys
+    app = QApplication(sys.argv)
+    window = MainWindow()
+    window.show()
+    sys.exit(app.exec_())

BIN
databases/Chinook_Sqlite.sqlite


+ 1 - 0
databases/tableview.py

@@ -4,6 +4,7 @@ from PyQt5.QtWidgets import QApplication, QMainWindow, QTableView
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.table = QTableView()

+ 4 - 3
databases/tableview_querymodel_parameter.py

@@ -2,12 +2,14 @@ import os
 
 from PyQt5.QtCore import QSize
 from PyQt5.QtSql import QSqlDatabase, QSqlQueryModel, QSqlQuery
-from PyQt5.QtWidgets import QApplication, QMainWindow, QTableView,QWidget, QHBoxLayout, QVBoxLayout, QLineEdit
+from PyQt5.QtWidgets import (QApplication, QMainWindow, QTableView, QWidget,
+                             QHBoxLayout, QVBoxLayout, QLineEdit)
 
 basedir = os.path.dirname(__file__)
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 
@@ -49,8 +51,7 @@ class MainWindow(QMainWindow):
             "inner join Album on Track.AlbumId = Album.AlbumId where "
             "Track.Name like '%' || :track_name || '%' and "
             "Track.composer like '%' || :composer_name || '%' and "
-            "Album.Title like '%' || :album_title || '%' "
-        )
+            "Album.Title like '%' || :album_title || '%' ")
 
         self.update_query()
 

+ 3 - 1
databases/tableview_relationalmodel.py

@@ -8,6 +8,7 @@ basedir = os.path.dirname(__file__)
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 
@@ -21,7 +22,8 @@ class MainWindow(QMainWindow):
         self.model.setTable("Track")
 
         self.model.setRelation(2, QSqlRelation("Album", "AlbumId", "Title"))
-        self.model.setRelation(3, QSqlRelation("MediaType", "MediaTypeId", "Name"))
+        self.model.setRelation(
+            3, QSqlRelation("MediaType", "MediaTypeId", "Name"))
         self.model.setRelation(4, QSqlRelation("Genre", "GenreId", "Name"))
 
         delegate = QSqlRelationalDelegate(self.table)

+ 1 - 0
databases/tableview_tablemodel.py

@@ -8,6 +8,7 @@ basedir = os.path.dirname(__file__)
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 3 - 1
databases/tableview_tablemodel_filter.py

@@ -9,6 +9,7 @@ basedir = os.path.dirname(__file__)
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 
@@ -27,7 +28,8 @@ class MainWindow(QMainWindow):
         self.db.setDatabaseName(os.path.join(basedir, "Chinook_Sqlite.sqlite"))
 
         if not self.db.open():
-            QMessageBox.critical(None, "Database Error", self.db.lastError().text())
+            QMessageBox.critical(None, "Database Error",
+                                 self.db.lastError().text())
             return
 
         self.model = QSqlTableModel(db=self.db)

+ 94 - 35
databases/widget_mapper.py

@@ -1,33 +1,28 @@
 import os
 import sys
-
 from PyQt5.QtCore import QSize, Qt
-from PyQt5.QtSql import QSqlDatabase, QSqlTableModel
-from PyQt5.QtWidgets import (
-    QApplication,
-    QComboBox,
-    QDataWidgetMapper,
-    QDoubleSpinBox,
-    QFormLayout,
-    QLabel,
-    QLineEdit,
-    QMainWindow,
-    QSpinBox,
-    QWidget,
-    QVBoxLayout,
-    QHBoxLayout,
-    QPushButton,
-)
+from PyQt5.QtSql import QSqlDatabase, QSqlTableModel, QSqlQuery
+from PyQt5.QtWidgets import (QApplication, QComboBox, QDataWidgetMapper,
+                             QDoubleSpinBox, QFormLayout, QLabel, QLineEdit,
+                             QMainWindow, QSpinBox, QWidget, QVBoxLayout,
+                             QHBoxLayout, QPushButton, QMessageBox, QStatusBar)
 
 basedir = os.path.dirname(__file__)
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
+        self.setWindowTitle("Track Editor")
+
+        # Initialize database first
+        if not self.initialize_database():
+            return
 
         form = QFormLayout()
 
+        # Create widgets
         self.track_id = QSpinBox()
         self.track_id.setRange(0, 2147483647)
         self.track_id.setDisabled(True)
@@ -49,60 +44,124 @@ class MainWindow(QMainWindow):
         self.unit_price.setSingleStep(0.01)
         self.unit_price.setPrefix("$")
 
+        # Populate ComboBoxes
+        self.populate_combo_boxes()
+
+        # Add form fields
         form.addRow(QLabel("Track ID"), self.track_id)
         form.addRow(QLabel("Track name"), self.name)
+        form.addRow(QLabel("Album"), self.album)
+        form.addRow(QLabel("Genre"), self.genre)
         form.addRow(QLabel("Composer"), self.composer)
         form.addRow(QLabel("Milliseconds"), self.milliseconds)
         form.addRow(QLabel("Bytes"), self.bytes)
         form.addRow(QLabel("Unit price"), self.unit_price)
 
-        print("driver list: ", ' '.join(QSqlDatabase.drivers()))
-        self.db = QSqlDatabase("QSQLITE")
-        self.db.setDatabaseName(os.path.join(basedir, "Chinook_Sqlite.sqlite"))
-        self.db.open()
-
+        # Setup model and mapper
         self.model = QSqlTableModel(db=self.db)
+        self.model.setTable("Track")
+        self.model.select()
 
         self.mapper = QDataWidgetMapper()
         self.mapper.setModel(self.model)
-
         self.mapper.addMapping(self.track_id, 0)
         self.mapper.addMapping(self.name, 1)
+        self.mapper.addMapping(self.album, 2)
+        self.mapper.addMapping(self.genre, 3)
         self.mapper.addMapping(self.composer, 5)
         self.mapper.addMapping(self.milliseconds, 6)
         self.mapper.addMapping(self.bytes, 7)
         self.mapper.addMapping(self.unit_price, 8)
 
-        self.model.setTable("Track")
-        self.model.select()
-
         self.mapper.toFirst()
 
-        self.setMinimumSize(QSize(400, 400))
-
+        # Create controls
         controls = QHBoxLayout()
         prev_rec = QPushButton("Previous")
-        prev_rec.clicked.connect(self.mapper.toPrevious)
+        prev_rec.clicked.connect(self.previous_record)
         next_rec = QPushButton("Next")
-        next_rec.clicked.connect(self.mapper.toNext)
+        next_rec.clicked.connect(self.next_record)
         save_rec = QPushButton("Save Changes")
-        save_rec.clicked.connect(self.mapper.submit)
+        save_rec.clicked.connect(self.save_changes)
 
         controls.addWidget(prev_rec)
         controls.addWidget(next_rec)
         controls.addWidget(save_rec)
 
-        form.setLabelAlignment(
-            Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTrailing | Qt.AlignmentFlag.AlignVCenter)
-
+        # Setup layouts
+        form.setLabelAlignment(Qt.AlignmentFlag.AlignLeft
+                               | Qt.AlignmentFlag.AlignTrailing
+                               | Qt.AlignmentFlag.AlignVCenter)
         layout = QVBoxLayout()
         layout.addLayout(form)
         layout.addLayout(controls)
 
         widget = QWidget()
         widget.setLayout(layout)
-
         self.setCentralWidget(widget)
+        self.setMinimumSize(QSize(400, 400))
+
+        # Add status bar
+        self.status_bar = QStatusBar()
+        self.setStatusBar(self.status_bar)
+        self.update_status()
+
+    def initialize_database(self):
+        """Initialize database connection with error handling"""
+        self.db = QSqlDatabase.addDatabase("QSQLITE")
+        self.db.setDatabaseName(os.path.join(basedir, "Chinook_Sqlite.sqlite"))
+
+        if not self.db.open():
+            QMessageBox.critical(
+                self, "Database Error",
+                "Could not open database file: " + self.db.lastError().text())
+            return False
+        return True
+
+    def populate_combo_boxes(self):
+        """Populate album and genre combo boxes from database"""
+        # Populate Albums
+        album_query = QSqlQuery("SELECT Title FROM Album ORDER BY Title")
+        while album_query.next():
+            self.album.addItem(album_query.value(0))
+
+        # Populate Genres
+        genre_query = QSqlQuery("SELECT Name FROM Genre ORDER BY Name")
+        while genre_query.next():
+            self.genre.addItem(genre_query.value(0))
+
+    def update_status(self):
+        """Update status bar with current record position"""
+        current = self.mapper.currentIndex() + 1
+        total = self.model.rowCount()
+        self.status_bar.showMessage(f"Record {current} of {total}")
+
+    def previous_record(self):
+        """Navigate to previous record and update status"""
+        self.mapper.toPrevious()
+        self.update_status()
+
+    def next_record(self):
+        """Navigate to next record and update status"""
+        self.mapper.toNext()
+        self.update_status()
+
+    def save_changes(self):
+        """Save changes with validation"""
+        if not self.name.text():
+            QMessageBox.warning(self, "Validation Error",
+                                "Track name cannot be empty")
+            return
+
+        if self.mapper.submit():
+            self.status_bar.showMessage("Changes saved successfully", 3000)
+        else:
+            QMessageBox.warning(self, "Save Error", "Failed to save changes")
+
+    def closeEvent(self, event):
+        """Clean up database connection when window closes"""
+        self.db.close()
+        super().closeEvent(event)
 
 
 if __name__ == "__main__":

+ 2 - 1
further/mvc_1.py

@@ -11,6 +11,7 @@ model = {
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle("MVC Example")
@@ -60,4 +61,4 @@ if __name__ == "__main__":
     app = QApplication(sys.argv)
     window = MainWindow()
     window.show()
-    app.exec_()
+    app.exec_()

+ 1 - 0
further/mvc_2.py

@@ -16,6 +16,7 @@ backups = []
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle("MVC Example")

+ 2 - 0
further/mvc_5.py

@@ -13,6 +13,7 @@ class DataModelSignals(QObject):
 
 
 class DataModel(UserDict):
+
     def __init__(self, *args, **kwargs):
         self.signals = DataModelSignals()
         super().__init__(*args, **kwargs)
@@ -60,6 +61,7 @@ controller = Controller()
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
         self.setWindowTitle("MVC Example")

+ 1 - 0
load_uifile.py

@@ -7,6 +7,7 @@ from MainWindow import Ui_MainWindow
 
 
 class MainWindow(QMainWindow, Ui_MainWindow):
+
     def __init__(self, *args, **kwargs):
         super(MainWindow, self).__init__(*args, **kwargs)
         self.setupUi(self)

+ 1 - 1
model-views/MainWindow.py

@@ -7,11 +7,11 @@
 # WARNING: Any manual changes made to this file will be lost when pyuic5 is
 # run again.  Do not edit this file unless you know what you are doing.
 
-
 from PyQt5 import QtCore, QtGui, QtWidgets
 
 
 class Ui_MainWindow(object):
+
     def setupUi(self, MainWindow):
         MainWindow.setObjectName("MainWindow")
         MainWindow.resize(280, 362)

+ 8 - 3
model-views/tableview_demo.py

@@ -5,11 +5,14 @@ from PyQt5.QtCore import QAbstractTableModel, Qt
 from PyQt5.QtGui import QColor
 from PyQt5.QtWidgets import QTableView, QMainWindow, QApplication
 
-COLORS = ['#053061', '#2166ac', '#4393c3', '#92c5de', '#d1e5f0', '#f7f7f7', '#fddbc7', '#f4a582', '#d6604d', '#b2182b',
-          '#67001f']
+COLORS = [
+    '#053061', '#2166ac', '#4393c3', '#92c5de', '#d1e5f0', '#f7f7f7',
+    '#fddbc7', '#f4a582', '#d6604d', '#b2182b', '#67001f'
+]
 
 
 class TableModel(QAbstractTableModel):
+
     def __init__(self, data):
         super(TableModel, self).__init__()
         self._data = data
@@ -27,7 +30,8 @@ class TableModel(QAbstractTableModel):
                 return QColor(COLORS[value])
         if role == Qt.ForegroundRole:
             value = self._data[index.row()][index.column()]
-            if (isinstance(value, int) or isinstance(value, float)) and value < 0:
+            if (isinstance(value, int)
+                    or isinstance(value, float)) and value < 0:
                 return QColor(Qt.red)
 
         if role == Qt.TextAlignmentRole:
@@ -64,6 +68,7 @@ class TableModel(QAbstractTableModel):
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
 

+ 2 - 0
model-views/tableview_numpy.py

@@ -6,6 +6,7 @@ from PyQt5.QtWidgets import QMainWindow, QTableView, QApplication
 
 
 class TableModel(QAbstractTableModel):
+
     def __init__(self, data):
         super(TableModel, self).__init__()
         self._data = data
@@ -23,6 +24,7 @@ class TableModel(QAbstractTableModel):
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 12 - 8
model-views/tableview_pandas.py

@@ -6,6 +6,7 @@ from PyQt5.QtWidgets import QMainWindow, QTableView, QApplication
 
 
 class TableModel(QAbstractTableModel):
+
     def __init__(self, data):
         super(TableModel, self).__init__()
         self._data = data
@@ -30,19 +31,22 @@ class TableModel(QAbstractTableModel):
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self):
         super().__init__()
 
         self.table = QTableView()
 
-        data = pd.DataFrame([
-            [1, 9, 2],
-            [4, 0, -1],
-            [7, 8, 9],
-            [3, 3, 2],
-            [5, 8, 9],
-        ],
-            columns=['a', 'b', 'c'], index=['Row 1', 'Row 2', 'Row 3', 'Row 4', 'Row 5'],
+        data = pd.DataFrame(
+            [
+                [1, 9, 2],
+                [4, 0, -1],
+                [7, 8, 9],
+                [3, 3, 2],
+                [5, 8, 9],
+            ],
+            columns=['a', 'b', 'c'],
+            index=['Row 1', 'Row 2', 'Row 3', 'Row 4', 'Row 5'],
         )
 
         self.model = TableModel(data)

+ 2 - 0
model-views/todo_1.py

@@ -14,6 +14,7 @@ flag = QImage(os.path.join(basedir, 'flag.png'))
 
 
 class TodoModel(QAbstractListModel):
+
     def __init__(self, todos=None):
         super().__init__()
         self.todos = todos or []
@@ -32,6 +33,7 @@ class TodoModel(QAbstractListModel):
 
 
 class MainWindow(QMainWindow, Ui_MainWindow):
+
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.setupUi(self)

+ 1 - 0
model-views/todo_skeleton.py

@@ -6,6 +6,7 @@ from MainWindow import Ui_MainWindow
 
 
 class MainWindow(QMainWindow, Ui_MainWindow):
+
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.setupUi(self)

+ 23 - 3
paint_app.py

@@ -5,14 +5,32 @@ from PyQt5 import QtWidgets, QtGui, QtCore
 
 COLORS = [
     # 17undertoneshttps://lospec.com/palette-list/17undertones
-    '#000000', '#141923', '#414168', '#3A7FA7', '#35E3E3', '#8FD970', '#5EBB49',
-    '#458352', '#DCD37B', '#FFFEE5', '#FFD035', '#CC9245', '#A15C3E', '#A42F3B',
-    '#F45B7A', '#C24998', '#81588D', '#BCB0C2', '#FFFFFF', ]
+    '#000000',
+    '#141923',
+    '#414168',
+    '#3A7FA7',
+    '#35E3E3',
+    '#8FD970',
+    '#5EBB49',
+    '#458352',
+    '#DCD37B',
+    '#FFFEE5',
+    '#FFD035',
+    '#CC9245',
+    '#A15C3E',
+    '#A42F3B',
+    '#F45B7A',
+    '#C24998',
+    '#81588D',
+    '#BCB0C2',
+    '#FFFFFF',
+]
 SPRAY_PARTICLES = 100
 SPRAY_DIAMMETER = 10
 
 
 class Canvas(QtWidgets.QLabel):
+
     def __init__(self):
         super().__init__()
         pixmap = QtGui.QPixmap(600, 300)
@@ -51,6 +69,7 @@ class Canvas(QtWidgets.QLabel):
 
 
 class QPaletteButton(QtWidgets.QPushButton):
+
     def __init__(self, color):
         super().__init__()
         self.setFixedSize(QtCore.QSize(24, 24))
@@ -59,6 +78,7 @@ class QPaletteButton(QtWidgets.QPushButton):
 
 
 class MainWindow(QtWidgets.QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 1 - 0
pixmap.py

@@ -4,6 +4,7 @@ from PyQt5 import QtWidgets, QtGui
 
 
 class MainWindow(QtWidgets.QMainWindow):
+
     def __init__(self):
         super().__init__()
 

+ 7 - 8
power_bar.py

@@ -3,13 +3,12 @@ from PyQt5.QtCore import Qt
 
 
 class _Bar(QtWidgets.QWidget):
+
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
 
-        self.setSizePolicy(
-            QtWidgets.QSizePolicy.MinimumExpanding,
-            QtWidgets.QSizePolicy.MinimumExpanding
-        )
+        self.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding,
+                           QtWidgets.QSizePolicy.MinimumExpanding)
 
     def sizeHint(self):
         return QtCore.QSize(40, 120)
@@ -19,7 +18,9 @@ class _Bar(QtWidgets.QWidget):
         brush = QtGui.QBrush()
         brush.setColor(QtGui.QColor('black'))
         brush.setStyle(Qt.SolidPattern)
-        rect = QtCore.QRect(0, 0, painter.device().width(), painter.device().height())
+        rect = QtCore.QRect(0, 0,
+                            painter.device().width(),
+                            painter.device().height())
         painter.fillRect(rect, brush)
 
         # Get current state.
@@ -46,9 +47,7 @@ class _Bar(QtWidgets.QWidget):
             rect = QtCore.QRect(
                 padding,
                 int(padding + d_height - ((n + 1) * step_size) + bar_spacer),
-                d_width,
-                bar_height
-            )
+                d_width, bar_height)
             painter.fillRect(rect, brush)
 
     def _trigger_refresh(self):

+ 6 - 8
power_bar_better.py

@@ -8,10 +8,8 @@ class _Bar(QtWidgets.QWidget):
     def __init__(self, steps, *args, **kwargs):
         super().__init__(*args, **kwargs)
 
-        self.setSizePolicy(
-            QtWidgets.QSizePolicy.MinimumExpanding,
-            QtWidgets.QSizePolicy.MinimumExpanding
-        )
+        self.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding,
+                           QtWidgets.QSizePolicy.MinimumExpanding)
 
         if isinstance(steps, list):
             # list of colors
@@ -35,7 +33,9 @@ class _Bar(QtWidgets.QWidget):
         brush = QtGui.QBrush()
         brush.setColor(self._background_color)
         brush.setStyle(Qt.SolidPattern)
-        rect = QtCore.QRect(0, 0, painter.device().width(), painter.device().height())
+        rect = QtCore.QRect(0, 0,
+                            painter.device().width(),
+                            painter.device().height())
         painter.fillRect(rect, brush)
 
         # Get current state.
@@ -61,9 +61,7 @@ class _Bar(QtWidgets.QWidget):
             rect = QtCore.QRect(
                 padding,
                 int(padding + d_height - ((n + 1) * step_size) + bar_spacer),
-                d_width,
-                bar_height
-            )
+                d_width, bar_height)
             painter.fillRect(rect, brush)
 
     def _trigger_refresh(self):

+ 1 - 0
signal_data.py

@@ -6,6 +6,7 @@ def my_custom_fn(n):
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self, *args, **kwargs):
         super(MainWindow, self).__init__(*args, **kwargs)
         self.setWindowTitle("My Awesome App")

+ 2 - 0
toolbars_and_menus.py

@@ -8,6 +8,7 @@ from PyQt5.QtGui import *
 
 # 自定义窗口,继承 QMainWindow
 class MainWindow(QMainWindow):
+
     def __init__(self, *args, **kwargs):
         super(MainWindow, self).__init__(*args, **kwargs)
         self.setWindowTitle("My Awesome App")  # 标题
@@ -63,6 +64,7 @@ class MainWindow(QMainWindow):
 
 
 class CustomDialog(QDialog):
+
     def __init__(self, *args, **kwargs):
         super(CustomDialog, self).__init__(*args, **kwargs)
         self.setWindowTitle("HELLO!")

+ 2 - 0
widgets.py

@@ -8,6 +8,7 @@ from PyQt5.QtWidgets import *
 
 # 自定义窗口,继承 QMainWindow
 class MainWindow(QMainWindow):
+
     def __init__(self, *args, **kwargs):
         super(MainWindow, self).__init__(*args, **kwargs)
         self.setWindowTitle("My Awesome App")  # 标题
@@ -60,6 +61,7 @@ class MainWindow(QMainWindow):
 
 
 class Color(QWidget):
+
     def __init__(self, color, *args, **kwargs):
         super(Color, self).__init__(*args, **kwargs)
         self.setAutoFillBackground(True)

+ 2 - 0
widgets_gridlayout.py

@@ -11,6 +11,7 @@ def index_changed(s):
 
 
 class MainWindow(QMainWindow):
+
     def __init__(self, *args, **kwargs):
         super(MainWindow, self).__init__(*args, **kwargs)
         self.setWindowTitle("My Awesome App")  # 标题
@@ -27,6 +28,7 @@ class MainWindow(QMainWindow):
 
 
 class Color(QWidget):
+
     def __init__(self, color, *args, **kwargs):
         super(Color, self).__init__(*args, **kwargs)
         self.setAutoFillBackground(True)

+ 4 - 1
widgets_stacklayout.py

@@ -7,6 +7,7 @@ from PyQt5.QtWidgets import *
 
 # 自定义窗口,继承 QMainWindow
 class MainWindow(QMainWindow):
+
     def __init__(self, *args, **kwargs):
         super(MainWindow, self).__init__(*args, **kwargs)
         self.setWindowTitle("My Awesome App")  # 标题
@@ -29,7 +30,8 @@ class MainWindow(QMainWindow):
         tabs.setTabPosition(QTabWidget.North)
         tabs.setMovable(True)
 
-        for n, color in enumerate(['red', 'green', 'blue', 'yellow', 'purple']):
+        for n, color in enumerate(['red', 'green', 'blue', 'yellow',
+                                   'purple']):
             tabs.addTab(Color(color), color)
 
         self.setCentralWidget(tabs)
@@ -39,6 +41,7 @@ class MainWindow(QMainWindow):
 
 
 class Color(QWidget):
+
     def __init__(self, color, *args, **kwargs):
         super(Color, self).__init__(*args, **kwargs)
         self.setAutoFillBackground(True)