diff --git a/Chapter03/calendar_app.py b/Chapter03/calendar_app.py
index 554b604..1a1540a 100644
--- a/Chapter03/calendar_app.py
+++ b/Chapter03/calendar_app.py
@@ -27,7 +27,10 @@ def __init__(self):
self.layout().addWidget(self.submit_btn)
self.cancel_btn = qtw.QPushButton(
'Cancel',
- clicked=self.destroy
+ # Errata: The book contains this line:
+ #clicked=self.destroy
+ # It should call self.close instead, like so:
+ clicked=self.close
)
self.layout().addWidget(self.cancel_btn)
self.show()
@@ -143,6 +146,11 @@ def clear_form(self):
self.event_detail.setPlainText('')
def populate_list(self):
+ # As reported by github user eramey16, we need the following line
+ # to unselect list items since the selected index may not exist
+ # in the new list. This line is not in the book code.
+ self.event_list.setCurrentRow(-1)
+
self.event_list.clear()
self.clear_form()
date = self.calendar.selectedDate()
diff --git a/Chapter04/text_editor.py b/Chapter04/text_editor.py
index 7060569..8e7698b 100644
--- a/Chapter04/text_editor.py
+++ b/Chapter04/text_editor.py
@@ -94,7 +94,10 @@ def __init__(self):
file_menu.addSeparator()
# add an action with a callback
- quit_action = file_menu.addAction('Quit', self.destroy)
+ # Errata: The book contains this line:
+ #quit_action = file_menu.addAction('Quit', self.destroy)
+ # It should call self.close instead, like so:
+ quit_action = file_menu.addAction('Quit', self.close)
# connect to a Qt Slot
edit_menu.addAction('Undo', self.textedit.undo)
@@ -269,7 +272,10 @@ def openFile(self):
with open(filename, 'r') as fh:
self.textedit.setText(fh.read())
except Exception as e:
- qtw.QMessageBox.critical(f"Could not load file: {e}")
+ # Errata: Book contains the following line:
+ #qtw.QMessageBox.critical(f"Could not load file: {e}")
+ # It should read like this:
+ qtw.QMessageBox.critical(self, f"Could not load file: {e}")
def saveFile(self):
filename, _ = qtw.QFileDialog.getSaveFileName(
@@ -283,7 +289,10 @@ def saveFile(self):
with open(filename, 'w') as fh:
fh.write(self.textedit.toPlainText())
except Exception as e:
- qtw.QMessageBox.critical(f"Could not save file: {e}")
+ # Errata: Book contains this line:
+ #qtw.QMessageBox.critical(f"Could not save file: {e}")
+ # It should read like this:
+ qtw.QMessageBox.critical(self, f"Could not load file: {e}")
def set_font(self):
current = self.textedit.currentFont()
diff --git a/Chapter05/csv_editor.py b/Chapter05/csv_editor.py
index 952ff84..b9403ad 100644
--- a/Chapter05/csv_editor.py
+++ b/Chapter05/csv_editor.py
@@ -85,7 +85,9 @@ def removeRows(self, position, rows, parent):
# method for saving
def save_data(self):
- with open(self.filename, 'w', encoding='utf-8') as fh:
+ # commented out code below to fix issue with additional lines being added after saving csv file from the window.
+ # with open(self.filename, 'w', encoding='utf-8') as fh:
+ with open(self.filename, 'w', newline='', encoding='utf-8') as fh:
writer = csv.writer(fh)
writer.writerow(self._headers)
writer.writerows(self._data)
@@ -152,8 +154,17 @@ def insert_below(self):
def remove_rows(self):
selected = self.tableview.selectedIndexes()
+ # Errata: The book contains the following code:
+ #if selected:
+ # self.model.removeRows(selected[0].row(), len(selected), None)
+
+ # This is incorrect, as len(selected) is the number of *cells* selected,
+ # not the number of *rows* selected.
+
+ # correct approach would look like this:
+ num_rows = len(set(index.row() for index in selected))
if selected:
- self.model.removeRows(selected[0].row(), len(selected), None)
+ self.model.removeRows(selected[0].row(), num_rows, None)
if __name__ == '__main__':
diff --git a/Chapter11/invoice_maker_printable.py b/Chapter11/invoice_maker_printable.py
index 43068fb..12ec06d 100644
--- a/Chapter11/invoice_maker_printable.py
+++ b/Chapter11/invoice_maker_printable.py
@@ -259,8 +259,14 @@ def _print_document(self):
self.preview.document().print(self.printer)
def print_dialog(self):
- self._print_document()
+ # Errata: the book contained this line:
+ #self._print_document()
+ # As noted by DevinLand in issue #8, this can cause the document to start printing.
dialog = qtps.QPrintDialog(self.printer, self)
+
+ # Instead we'll add this line, so _print_document is triggered when the dialog is
+ # accepted:
+ dialog.accepted.connect(self._print_document)
dialog.exec()
self._update_preview_size()
diff --git a/Chapter17/QTicTacToe/README.rst b/Chapter17/QTicTacToe/README.rst
index c2d8ef4..c111eed 100644
--- a/Chapter17/QTicTacToe/README.rst
+++ b/Chapter17/QTicTacToe/README.rst
@@ -14,7 +14,7 @@ This is the classic game of **tic-tac-toe**, also known as noughts and crosses.
Usage
=====
-Simply run `python qtictactoe.py` from within the project folder.
+Simply run `python run.py` from within the project folder.
- Players take turns clicking the mouse on the playing field to mark squares.
- When one player gets 3 in a row, they win.
diff --git a/README.md b/README.md
index 1f2a6f9..02d948b 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
+
+
+
# Mastering GUI Programming with Python
@@ -61,6 +64,18 @@ We also provide a PDF file that has color images of the screenshots/diagrams use
Click on the following link to see the Code in Action: [Click here to view the videos](http://bit.ly/2M3QVrl)
+## Errata
+
+Page 77: The section of code that describes the "on_category_change" method:
+* Line 3 reads, "dialog = CategoryWindow()", it should read, "self.dialog = CategoryWindow()"
+* Line 4 reads, "dialog.submitted.connect(self.add_category)", it should read, "self.dialog.submitted.connect(self.add_category)"
+
+Page 418:
+* Here is the ```=__init__()``` method _should be_ Here is the ```__init__()``` method
+
+Page 419:
+* The ```mousePressEvent())``` method is called _should be_ The ```mousePressEvent()``` method is called
+
### Related products
* Qt5 Python GUI Programming Cookbook [[Packt]](https://www.packtpub.com/application-development/qt5-python-gui-programming-cookbook?utm_source=github&utm_medium=repository&utm_campaign=) [[Amazon]](https://www.amazon.com/dp/B079S4Q9T2)
@@ -81,3 +96,7 @@ is a data analyst and software developer who has been solving problems with Pyth
[Click here](https://docs.google.com/forms/d/e/1FAIpQLSdy7dATC6QmEL81FIUuymZ0Wy9vH1jHkvpY57OiMeKGqib_Ow/viewform) if you have any feedback or suggestions.
+### Download a free PDF
+
+ If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
+