├── Chapter05 ├── my_module │ ├── __init__.py │ ├── submodule_2 │ │ ├── __init__.py │ │ └── submodule_a.py │ └── submodule_1.py ├── my_module.py ├── ABQ_Data_Entry │ ├── abq_data_entry │ │ ├── __init__.py │ │ ├── constants.py │ │ └── application.py │ ├── .gitignore │ ├── abq_data_entry.py │ ├── docs │ │ ├── Application_layout.png │ │ └── lab-tech-paper-form.png │ └── README.rst ├── ABQ_Data_Entry_skeleton │ └── abq_data_entry │ │ ├── models.py │ │ ├── views.py │ │ ├── __init__.py │ │ ├── application.py │ │ └── widgets.py └── rst_example.rst ├── Chapter06 ├── ABQ_Data_Entry │ ├── abq_data_entry │ │ ├── __init__.py │ │ └── constants.py │ ├── .gitignore │ ├── abq_data_entry.py │ ├── docs │ │ ├── Application_layout.png │ │ └── lab-tech-paper-form.png │ └── README.rst ├── messagebox_demo_short.py ├── messagebox_demo.py ├── filedialog_demo.py └── menu_demo.py ├── Chapter07 ├── ABQ_Data_Entry │ ├── abq_data_entry │ │ ├── __init__.py │ │ └── constants.py │ ├── .gitignore │ ├── abq_data_entry.py │ ├── docs │ │ ├── Application_layout.png │ │ └── lab-tech-paper-form.png │ └── README.rst └── treeview_demo.py ├── Chapter08 ├── ABQ_Data_Entry │ ├── abq_data_entry │ │ ├── __init__.py │ │ ├── constants.py │ │ └── images │ │ │ ├── abq_logo-16x10.png │ │ │ ├── abq_logo-32x20.png │ │ │ ├── abq_logo-64x40.png │ │ │ └── __init__.py │ ├── .gitignore │ ├── abq_data_entry.py │ ├── docs │ │ ├── Application_layout.png │ │ └── lab-tech-paper-form.png │ └── README.rst ├── smile.gif ├── tkinter_color_demo.py ├── tk_default_font_example.py ├── font_lister.py ├── image_scope_demo.py ├── tags_demo.py ├── font_demo.py ├── image_viewer_demo.py └── ttk_combobox_info.py ├── Chapter09 ├── ABQ_Data_Entry │ ├── abq_data_entry │ │ ├── __init__.py │ │ ├── test │ │ │ └── __init__.py │ │ ├── constants.py │ │ └── images │ │ │ ├── abq_logo-16x10.png │ │ │ ├── abq_logo-32x20.png │ │ │ ├── abq_logo-64x40.png │ │ │ └── __init__.py │ ├── .gitignore │ ├── abq_data_entry.py │ ├── docs │ │ ├── Application_layout.png │ │ └── lab-tech-paper-form.png │ └── README.rst └── unittest_demo │ ├── test_mycalc_no_unittest.py │ ├── test_mycalc_badly.py │ ├── mycalc.py │ └── test_mycalc.py ├── Chapter10 └── ABQ_Data_Entry │ ├── abq_data_entry │ ├── __init__.py │ ├── test │ │ ├── __init__.py │ │ └── support.py │ ├── constants.py │ └── images │ │ ├── abq_logo-16x10.png │ │ ├── abq_logo-32x20.png │ │ ├── abq_logo-64x40.png │ │ └── __init__.py │ ├── requirements.txt │ ├── .gitignore │ ├── abq_data_entry.py │ ├── docs │ ├── Application_layout.png │ └── lab-tech-paper-form.png │ ├── sql │ └── populate_db.sql │ └── README.rst ├── Chapter11 ├── ABQ_Data_Entry │ ├── abq_data_entry │ │ ├── __init__.py │ │ ├── test │ │ │ ├── __init__.py │ │ │ └── support.py │ │ ├── constants.py │ │ ├── images │ │ │ ├── abq_logo-16x10.png │ │ │ ├── abq_logo-32x20.png │ │ │ ├── abq_logo-64x40.png │ │ │ └── __init__.py │ │ └── network.py │ ├── requirements.txt │ ├── .gitignore │ ├── abq_data_entry.py │ ├── docs │ │ ├── Application_layout.png │ │ └── lab-tech-paper-form.png │ ├── sql │ │ └── populate_db.sql │ └── README.rst ├── ftp_retr_demo.py ├── basic_ftp_server.py ├── urllib_examples.py ├── requests_example.py └── sample_http_server.py ├── Chapter12 ├── ABQ_Data_Entry │ ├── abq_data_entry │ │ ├── __init__.py │ │ ├── test │ │ │ ├── __init__.py │ │ │ └── support.py │ │ ├── constants.py │ │ └── images │ │ │ ├── abq_logo-16x10.png │ │ │ ├── abq_logo-32x20.png │ │ │ ├── abq_logo-64x40.png │ │ │ └── __init__.py │ ├── requirements.txt │ ├── .gitignore │ ├── abq_data_entry.py │ ├── docs │ │ ├── Application_layout.png │ │ └── lab-tech-paper-form.png │ ├── sql │ │ └── populate_db.sql │ └── README.rst ├── smile.gif └── simple_canvas_demo.py ├── Chapter21 ├── scene.jpg ├── coloredball.jpg ├── __pycache__ │ ├── demoAnimation1.cpython-35.pyc │ ├── demoAnimation1.cpython-36.pyc │ ├── demoAnimation3.cpython-35.pyc │ ├── demoAnimation3.cpython-36.pyc │ ├── demoAnimation4.cpython-35.pyc │ ├── demoAnimation4.cpython-36.pyc │ ├── demoGraphicsView.cpython-35.pyc │ └── demoGraphicsView.cpython-36.pyc ├── demoGraphicsView.ui ├── callGraphicsView.pyw ├── callAnimation1.pyw ├── demoGraphicsView.py ├── callAnimation3.pyw ├── demoAnimation3.ui ├── demoAnimation1.ui ├── demoAnimation4.ui ├── demoAnimation4.py ├── callAnimation4.pyw ├── demoAnimation3.py └── demoAnimation1.py ├── Chapter20 ├── lineIcon.ico ├── circleIcon.ico ├── rectangleIcon.ico ├── __pycache__ │ ├── demoDrawCircle.cpython-35.pyc │ ├── demoDrawLine.cpython-35.pyc │ └── demoMousetrack.cpython-35.pyc ├── iconresource.qrc ├── demoPlotBars.py ├── demoPlotLine.py ├── callMouseTrack.pyw ├── demoDrawDot.ui ├── demoDrawLine.ui ├── demoDrawCircle.ui ├── demoDrawRectangle.ui ├── callDrawDot.pyw ├── callMouseClickCoordinates.pyw ├── callDrawLine.pyw ├── callDrawRectangle.pyw ├── callDrawText.pyw ├── demoDrawDot.py ├── demoDrawLine.py ├── callDrawCircle.pyw ├── demoDrawCircle.py ├── demoDrawRectangle.py ├── demoMousetrack.ui ├── demoMousetrack.py ├── demoMouseClicks.ui ├── callDrawDiffLine.pyw ├── demoDrawDiffLine.ui ├── demoMouseClicks.py └── callToolBars.pyw ├── Chapter14 ├── __pycache__ │ ├── demoSpinBox.cpython-35.pyc │ ├── demoComboBox.cpython-35.pyc │ ├── demoComboBox1.cpython-35.pyc │ ├── demoFontComboBox.cpython-35.pyc │ ├── demoProgressBar.cpython-35.pyc │ └── demoSignalSlot1.cpython-35.pyc ├── calldemoSignalSlot1.pyw ├── callProgressBar.pyw ├── callListWidget1.pyw ├── callComboBox.pyw ├── callListWidget3.pyw ├── callFontComboBox.pyw ├── callListWidget2.pyw ├── callScrollBar.pyw ├── calldemoSpinner.pyw ├── callListWidgetOp.pyw ├── demoProgressBar.ui ├── demoFontComboBox.ui ├── demoSignalSlot1.py ├── demoProgressBar.py ├── demoListWidget3.ui ├── demoFontComboBox.py └── demoComboBox.ui ├── Chapter22 ├── __pycache__ │ ├── demoBrowser.cpython-35.pyc │ ├── demoGoogleMap1.cpython-35.pyc │ └── showGoogleMap.cpython-35.pyc ├── callGoogleMap.pyw ├── callGoogleMap3.pyw ├── callGoogleMap2.pyw └── callGoogleMap1.pyw ├── Chapter13 ├── __pycache__ │ ├── demoLineEdit.cpython-35.pyc │ └── demoRadioButton1.cpython-35.pyc ├── callLineEdit.pyw ├── callRadioButton1.pyw ├── callCheckBox1.pyw ├── callCheckBox2.pyw ├── callRadioButton2.pyw ├── demoLineEdit.py └── demoLineEdit.ui ├── Chapter01 ├── hello_tkinter.py └── better_hello_tkinter.py ├── Chapter03 ├── boilerplate.py ├── entry_example.py ├── discrete_label_input_example.py ├── checkbutton_example.py ├── combobox_example.py ├── spinbox_example.py ├── button_example.py └── text_widget_example.py ├── Chapter04 ├── FiveCharEntry.py ├── MixinExample.py ├── FiveCharEntry2.py ├── DateEntry.py └── ValidatedSpinboxNoDynamic.py ├── Chapter16 ├── callFontDialog.pyw ├── callInputDialog.pyw ├── callColorDialog.pyw ├── demoFontDialog.ui ├── demoFontDialog.py ├── callFileDialog.pyw ├── demoInputDialog.ui ├── demoFileDialog.ui ├── demoInputDialog.py ├── demoColorDialog.py └── demoColorDialog.ui ├── Chapter15 ├── callLineEditClass.pyw ├── callStudentClass.pyw ├── callSimpleInheritance.pyw ├── LineEditClass.py ├── callMultipleInheritance.pyw ├── LineEditClass.ui └── callMultilevelInheritance.pyw ├── Chapter19 ├── callDatabase.pyw ├── callInsertRows.pyw ├── callSignInForm.pyw ├── callSearchRows.pyw ├── callDisplayRows.pyw ├── callCreateTable.pyw ├── callChangePassword.pyw └── demoDatabase.ui ├── LICENSE └── Chapter18 └── demoBrowser.py /Chapter05/my_module/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter05/my_module.py: -------------------------------------------------------------------------------- 1 | import my_module 2 | -------------------------------------------------------------------------------- /Chapter05/my_module/submodule_2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter05/my_module/submodule_2/submodule_a.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry/abq_data_entry/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter06/ABQ_Data_Entry/abq_data_entry/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter07/ABQ_Data_Entry/abq_data_entry/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter08/ABQ_Data_Entry/abq_data_entry/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/abq_data_entry/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/abq_data_entry/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/abq_data_entry/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/abq_data_entry/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry_skeleton/abq_data_entry/models.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry_skeleton/abq_data_entry/views.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/abq_data_entry/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/abq_data_entry/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/requirements.txt: -------------------------------------------------------------------------------- 1 | psycopg2 2 | -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/abq_data_entry/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/requirements.txt: -------------------------------------------------------------------------------- 1 | psycopg2 2 | -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/abq_data_entry/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/requirements.txt: -------------------------------------------------------------------------------- 1 | psycopg2 2 | -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__/ 3 | -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry_skeleton/abq_data_entry/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry_skeleton/abq_data_entry/application.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry_skeleton/abq_data_entry/widgets.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter06/ABQ_Data_Entry/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__/ 3 | -------------------------------------------------------------------------------- /Chapter07/ABQ_Data_Entry/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__/ 3 | -------------------------------------------------------------------------------- /Chapter08/ABQ_Data_Entry/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__/ 3 | -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__/ 3 | -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__/ 3 | -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__/ 3 | -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__/ 3 | -------------------------------------------------------------------------------- /Chapter05/my_module/submodule_1.py: -------------------------------------------------------------------------------- 1 | from .submodule_2 import submodule_a 2 | -------------------------------------------------------------------------------- /Chapter08/smile.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter08/smile.gif -------------------------------------------------------------------------------- /Chapter12/smile.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter12/smile.gif -------------------------------------------------------------------------------- /Chapter21/scene.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter21/scene.jpg -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry/abq_data_entry.py: -------------------------------------------------------------------------------- 1 | from abq_data_entry.application import Application 2 | 3 | app = Application() 4 | app.mainloop() 5 | -------------------------------------------------------------------------------- /Chapter06/ABQ_Data_Entry/abq_data_entry.py: -------------------------------------------------------------------------------- 1 | from abq_data_entry.application import Application 2 | 3 | app = Application() 4 | app.mainloop() 5 | -------------------------------------------------------------------------------- /Chapter07/ABQ_Data_Entry/abq_data_entry.py: -------------------------------------------------------------------------------- 1 | from abq_data_entry.application import Application 2 | 3 | app = Application() 4 | app.mainloop() 5 | -------------------------------------------------------------------------------- /Chapter08/ABQ_Data_Entry/abq_data_entry.py: -------------------------------------------------------------------------------- 1 | from abq_data_entry.application import Application 2 | 3 | app = Application() 4 | app.mainloop() 5 | -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/abq_data_entry.py: -------------------------------------------------------------------------------- 1 | from abq_data_entry.application import Application 2 | 3 | app = Application() 4 | app.mainloop() 5 | -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/abq_data_entry.py: -------------------------------------------------------------------------------- 1 | from abq_data_entry.application import Application 2 | 3 | app = Application() 4 | app.mainloop() 5 | -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/abq_data_entry.py: -------------------------------------------------------------------------------- 1 | from abq_data_entry.application import Application 2 | 3 | app = Application() 4 | app.mainloop() 5 | -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/abq_data_entry.py: -------------------------------------------------------------------------------- 1 | from abq_data_entry.application import Application 2 | 3 | app = Application() 4 | app.mainloop() 5 | -------------------------------------------------------------------------------- /Chapter20/lineIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter20/lineIcon.ico -------------------------------------------------------------------------------- /Chapter20/circleIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter20/circleIcon.ico -------------------------------------------------------------------------------- /Chapter21/coloredball.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter21/coloredball.jpg -------------------------------------------------------------------------------- /Chapter20/rectangleIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter20/rectangleIcon.ico -------------------------------------------------------------------------------- /Chapter14/__pycache__/demoSpinBox.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter14/__pycache__/demoSpinBox.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter22/__pycache__/demoBrowser.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter22/__pycache__/demoBrowser.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter13/__pycache__/demoLineEdit.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter13/__pycache__/demoLineEdit.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter14/__pycache__/demoComboBox.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter14/__pycache__/demoComboBox.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter14/__pycache__/demoComboBox1.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter14/__pycache__/demoComboBox1.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter20/__pycache__/demoDrawCircle.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter20/__pycache__/demoDrawCircle.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter20/__pycache__/demoDrawLine.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter20/__pycache__/demoDrawLine.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter20/__pycache__/demoMousetrack.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter20/__pycache__/demoMousetrack.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter21/__pycache__/demoAnimation1.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter21/__pycache__/demoAnimation1.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter21/__pycache__/demoAnimation1.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter21/__pycache__/demoAnimation1.cpython-36.pyc -------------------------------------------------------------------------------- /Chapter21/__pycache__/demoAnimation3.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter21/__pycache__/demoAnimation3.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter21/__pycache__/demoAnimation3.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter21/__pycache__/demoAnimation3.cpython-36.pyc -------------------------------------------------------------------------------- /Chapter21/__pycache__/demoAnimation4.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter21/__pycache__/demoAnimation4.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter21/__pycache__/demoAnimation4.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter21/__pycache__/demoAnimation4.cpython-36.pyc -------------------------------------------------------------------------------- /Chapter22/__pycache__/demoGoogleMap1.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter22/__pycache__/demoGoogleMap1.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter22/__pycache__/showGoogleMap.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter22/__pycache__/showGoogleMap.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry/docs/Application_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter05/ABQ_Data_Entry/docs/Application_layout.png -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry/docs/lab-tech-paper-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter05/ABQ_Data_Entry/docs/lab-tech-paper-form.png -------------------------------------------------------------------------------- /Chapter06/ABQ_Data_Entry/docs/Application_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter06/ABQ_Data_Entry/docs/Application_layout.png -------------------------------------------------------------------------------- /Chapter06/ABQ_Data_Entry/docs/lab-tech-paper-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter06/ABQ_Data_Entry/docs/lab-tech-paper-form.png -------------------------------------------------------------------------------- /Chapter07/ABQ_Data_Entry/docs/Application_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter07/ABQ_Data_Entry/docs/Application_layout.png -------------------------------------------------------------------------------- /Chapter07/ABQ_Data_Entry/docs/lab-tech-paper-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter07/ABQ_Data_Entry/docs/lab-tech-paper-form.png -------------------------------------------------------------------------------- /Chapter08/ABQ_Data_Entry/docs/Application_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter08/ABQ_Data_Entry/docs/Application_layout.png -------------------------------------------------------------------------------- /Chapter08/ABQ_Data_Entry/docs/lab-tech-paper-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter08/ABQ_Data_Entry/docs/lab-tech-paper-form.png -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/docs/Application_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter09/ABQ_Data_Entry/docs/Application_layout.png -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/docs/lab-tech-paper-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter09/ABQ_Data_Entry/docs/lab-tech-paper-form.png -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/docs/Application_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter10/ABQ_Data_Entry/docs/Application_layout.png -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/docs/lab-tech-paper-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter10/ABQ_Data_Entry/docs/lab-tech-paper-form.png -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/docs/Application_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter11/ABQ_Data_Entry/docs/Application_layout.png -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/docs/lab-tech-paper-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter11/ABQ_Data_Entry/docs/lab-tech-paper-form.png -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/docs/Application_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter12/ABQ_Data_Entry/docs/Application_layout.png -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/docs/lab-tech-paper-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter12/ABQ_Data_Entry/docs/lab-tech-paper-form.png -------------------------------------------------------------------------------- /Chapter13/__pycache__/demoRadioButton1.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter13/__pycache__/demoRadioButton1.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter14/__pycache__/demoFontComboBox.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter14/__pycache__/demoFontComboBox.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter14/__pycache__/demoProgressBar.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter14/__pycache__/demoProgressBar.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter14/__pycache__/demoSignalSlot1.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter14/__pycache__/demoSignalSlot1.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter21/__pycache__/demoGraphicsView.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter21/__pycache__/demoGraphicsView.cpython-35.pyc -------------------------------------------------------------------------------- /Chapter21/__pycache__/demoGraphicsView.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter21/__pycache__/demoGraphicsView.cpython-36.pyc -------------------------------------------------------------------------------- /Chapter20/iconresource.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | circleIcon.ico 4 | rectangleIcon.ico 5 | lineIcon.ico 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry/abq_data_entry/constants.py: -------------------------------------------------------------------------------- 1 | class FieldTypes: 2 | string = 1 3 | string_list = 2 4 | iso_date_string = 3 5 | long_string = 4 6 | decimal = 5 7 | integer = 6 8 | boolean = 7 9 | -------------------------------------------------------------------------------- /Chapter06/ABQ_Data_Entry/abq_data_entry/constants.py: -------------------------------------------------------------------------------- 1 | class FieldTypes: 2 | string = 1 3 | string_list = 2 4 | iso_date_string = 3 5 | long_string = 4 6 | decimal = 5 7 | integer = 6 8 | boolean = 7 9 | -------------------------------------------------------------------------------- /Chapter07/ABQ_Data_Entry/abq_data_entry/constants.py: -------------------------------------------------------------------------------- 1 | class FieldTypes: 2 | string = 1 3 | string_list = 2 4 | iso_date_string = 3 5 | long_string = 4 6 | decimal = 5 7 | integer = 6 8 | boolean = 7 9 | -------------------------------------------------------------------------------- /Chapter08/ABQ_Data_Entry/abq_data_entry/constants.py: -------------------------------------------------------------------------------- 1 | class FieldTypes: 2 | string = 1 3 | string_list = 2 4 | iso_date_string = 3 5 | long_string = 4 6 | decimal = 5 7 | integer = 6 8 | boolean = 7 9 | -------------------------------------------------------------------------------- /Chapter08/ABQ_Data_Entry/abq_data_entry/images/abq_logo-16x10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter08/ABQ_Data_Entry/abq_data_entry/images/abq_logo-16x10.png -------------------------------------------------------------------------------- /Chapter08/ABQ_Data_Entry/abq_data_entry/images/abq_logo-32x20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter08/ABQ_Data_Entry/abq_data_entry/images/abq_logo-32x20.png -------------------------------------------------------------------------------- /Chapter08/ABQ_Data_Entry/abq_data_entry/images/abq_logo-64x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter08/ABQ_Data_Entry/abq_data_entry/images/abq_logo-64x40.png -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/abq_data_entry/constants.py: -------------------------------------------------------------------------------- 1 | class FieldTypes: 2 | string = 1 3 | string_list = 2 4 | iso_date_string = 3 5 | long_string = 4 6 | decimal = 5 7 | integer = 6 8 | boolean = 7 9 | -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/abq_data_entry/images/abq_logo-16x10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter09/ABQ_Data_Entry/abq_data_entry/images/abq_logo-16x10.png -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/abq_data_entry/images/abq_logo-32x20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter09/ABQ_Data_Entry/abq_data_entry/images/abq_logo-32x20.png -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/abq_data_entry/images/abq_logo-64x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter09/ABQ_Data_Entry/abq_data_entry/images/abq_logo-64x40.png -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/abq_data_entry/constants.py: -------------------------------------------------------------------------------- 1 | class FieldTypes: 2 | string = 1 3 | string_list = 2 4 | iso_date_string = 3 5 | long_string = 4 6 | decimal = 5 7 | integer = 6 8 | boolean = 7 9 | -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/abq_data_entry/images/abq_logo-16x10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter10/ABQ_Data_Entry/abq_data_entry/images/abq_logo-16x10.png -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/abq_data_entry/images/abq_logo-32x20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter10/ABQ_Data_Entry/abq_data_entry/images/abq_logo-32x20.png -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/abq_data_entry/images/abq_logo-64x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter10/ABQ_Data_Entry/abq_data_entry/images/abq_logo-64x40.png -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/abq_data_entry/constants.py: -------------------------------------------------------------------------------- 1 | class FieldTypes: 2 | string = 1 3 | string_list = 2 4 | iso_date_string = 3 5 | long_string = 4 6 | decimal = 5 7 | integer = 6 8 | boolean = 7 9 | -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/abq_data_entry/images/abq_logo-16x10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter11/ABQ_Data_Entry/abq_data_entry/images/abq_logo-16x10.png -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/abq_data_entry/images/abq_logo-32x20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter11/ABQ_Data_Entry/abq_data_entry/images/abq_logo-32x20.png -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/abq_data_entry/images/abq_logo-64x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter11/ABQ_Data_Entry/abq_data_entry/images/abq_logo-64x40.png -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/abq_data_entry/constants.py: -------------------------------------------------------------------------------- 1 | class FieldTypes: 2 | string = 1 3 | string_list = 2 4 | iso_date_string = 3 5 | long_string = 4 6 | decimal = 5 7 | integer = 6 8 | boolean = 7 9 | -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/abq_data_entry/images/abq_logo-16x10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter12/ABQ_Data_Entry/abq_data_entry/images/abq_logo-16x10.png -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/abq_data_entry/images/abq_logo-32x20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter12/ABQ_Data_Entry/abq_data_entry/images/abq_logo-32x20.png -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/abq_data_entry/images/abq_logo-64x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Python-GUI-Programming-A-Complete-Reference-Guide/HEAD/Chapter12/ABQ_Data_Entry/abq_data_entry/images/abq_logo-64x40.png -------------------------------------------------------------------------------- /Chapter20/demoPlotBars.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as graph 2 | 3 | years = ['2016', '2017', '2018'] 4 | profit = [70, 90, 80] 5 | graph.bar(years, profit) 6 | graph.title('Growth in Business') 7 | graph.plot(100) 8 | graph.show() 9 | -------------------------------------------------------------------------------- /Chapter06/messagebox_demo_short.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import messagebox 3 | 4 | messagebox.showinfo( 5 | title='This is the title', 6 | message="This is the message", 7 | detail='This is the detail' 8 | ) 9 | -------------------------------------------------------------------------------- /Chapter20/demoPlotLine.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as graph 2 | 3 | graph.title('Plotting a Line!') 4 | graph.xlabel('x - axis') 5 | graph.ylabel('y - axis') 6 | x = [10,20,30] 7 | y = [20,40,60] 8 | graph.plot(x, y) 9 | graph.show() 10 | -------------------------------------------------------------------------------- /Chapter01/hello_tkinter.py: -------------------------------------------------------------------------------- 1 | """Hello World application for Tkinter""" 2 | 3 | 4 | from tkinter import * 5 | from tkinter.ttk 6 | import * 7 | 8 | root = Tk() 9 | 10 | label = Label(root, text="Hello World") 11 | label.pack() 12 | root.mainloop() 13 | -------------------------------------------------------------------------------- /Chapter08/tkinter_color_demo.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | 3 | l = tk.Label(text='Hot Dog!', fg='yellow', bg='red') 4 | l.pack(expand=1, fill='both') 5 | 6 | l2 = tk.Label(text='Also Hot Dog!', foreground='#FFFF00', background='#FF0000') 7 | l2.pack(expand=1, fill='both') 8 | -------------------------------------------------------------------------------- /Chapter03/boilerplate.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | 4 | # Start coding here 5 | 6 | 7 | class Application(tk.Tk): 8 | """Application root window""" 9 | 10 | if __name__ == "__main__": 11 | app = Application() 12 | app.mainloop() 13 | -------------------------------------------------------------------------------- /Chapter03/entry_example.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | 4 | parent = tk.Tk() 5 | my_text_var = tk.StringVar() 6 | 7 | my_entry = ttk.Entry( 8 | parent, 9 | textvariable=my_text_var 10 | ) 11 | my_entry.pack() 12 | 13 | parent.mainloop() 14 | -------------------------------------------------------------------------------- /Chapter03/discrete_label_input_example.py: -------------------------------------------------------------------------------- 1 | from tkinter import Frame, Label, Entry 2 | 3 | form = Frame() 4 | label = Label(form, text='Name') 5 | name_input = Entry(form) 6 | label.grid(row=0, column=0) 7 | name_input.grid(row=1, column=0) 8 | 9 | form.pack() 10 | form.mainloop() 11 | -------------------------------------------------------------------------------- /Chapter03/checkbutton_example.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | 4 | parent = tk.Tk() 5 | my_boolean_var = tk.BooleanVar() 6 | 7 | my_checkbutton = ttk.Checkbutton( 8 | text="Check to make this option True", 9 | variable=my_boolean_var 10 | ) 11 | my_checkbutton.pack() 12 | parent.mainloop() 13 | -------------------------------------------------------------------------------- /Chapter08/ABQ_Data_Entry/abq_data_entry/images/__init__.py: -------------------------------------------------------------------------------- 1 | from os import path 2 | 3 | IMAGE_DIRECTORY = path.dirname(__file__) 4 | 5 | ABQ_LOGO_16 = path.join(IMAGE_DIRECTORY, 'abq_logo-16x10.png') 6 | ABQ_LOGO_32 = path.join(IMAGE_DIRECTORY, 'abq_logo-32x20.png') 7 | ABQ_LOGO_64 = path.join(IMAGE_DIRECTORY, 'abq_logo-64x40.png') 8 | -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/abq_data_entry/images/__init__.py: -------------------------------------------------------------------------------- 1 | from os import path 2 | 3 | IMAGE_DIRECTORY = path.dirname(__file__) 4 | 5 | ABQ_LOGO_16 = path.join(IMAGE_DIRECTORY, 'abq_logo-16x10.png') 6 | ABQ_LOGO_32 = path.join(IMAGE_DIRECTORY, 'abq_logo-32x20.png') 7 | ABQ_LOGO_64 = path.join(IMAGE_DIRECTORY, 'abq_logo-64x40.png') 8 | -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/abq_data_entry/images/__init__.py: -------------------------------------------------------------------------------- 1 | from os import path 2 | 3 | IMAGE_DIRECTORY = path.dirname(__file__) 4 | 5 | ABQ_LOGO_16 = path.join(IMAGE_DIRECTORY, 'abq_logo-16x10.png') 6 | ABQ_LOGO_32 = path.join(IMAGE_DIRECTORY, 'abq_logo-32x20.png') 7 | ABQ_LOGO_64 = path.join(IMAGE_DIRECTORY, 'abq_logo-64x40.png') 8 | -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/abq_data_entry/images/__init__.py: -------------------------------------------------------------------------------- 1 | from os import path 2 | 3 | IMAGE_DIRECTORY = path.dirname(__file__) 4 | 5 | ABQ_LOGO_16 = path.join(IMAGE_DIRECTORY, 'abq_logo-16x10.png') 6 | ABQ_LOGO_32 = path.join(IMAGE_DIRECTORY, 'abq_logo-32x20.png') 7 | ABQ_LOGO_64 = path.join(IMAGE_DIRECTORY, 'abq_logo-64x40.png') 8 | -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/abq_data_entry/images/__init__.py: -------------------------------------------------------------------------------- 1 | from os import path 2 | 3 | IMAGE_DIRECTORY = path.dirname(__file__) 4 | 5 | ABQ_LOGO_16 = path.join(IMAGE_DIRECTORY, 'abq_logo-16x10.png') 6 | ABQ_LOGO_32 = path.join(IMAGE_DIRECTORY, 'abq_logo-32x20.png') 7 | ABQ_LOGO_64 = path.join(IMAGE_DIRECTORY, 'abq_logo-64x40.png') 8 | -------------------------------------------------------------------------------- /Chapter03/combobox_example.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | 4 | parent = tk.Tk() 5 | my_string_var = tk.StringVar() 6 | 7 | combobox = ttk.Combobox( 8 | parent, 9 | textvariable=my_string_var, 10 | values=["Option 1", "Option 2", "Option 3"] 11 | ) 12 | combobox.pack() 13 | parent.mainloop() 14 | -------------------------------------------------------------------------------- /Chapter03/spinbox_example.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | 4 | parent = tk.Tk() 5 | my_double_var = tk.DoubleVar() 6 | 7 | my_spinbox = tk.Spinbox( 8 | parent, 9 | from_=0.5, 10 | to=52.0, 11 | increment=.01, 12 | textvariable=my_double_var 13 | ) 14 | my_spinbox.pack() 15 | parent.mainloop() 16 | -------------------------------------------------------------------------------- /Chapter03/button_example.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | 4 | parent = tk.Tk() 5 | 6 | tvar = tk.StringVar() 7 | def swaptext(): 8 | tvar.set('There' if tvar.get() == 'Hi' else 'Hi') 9 | 10 | my_button = ttk.Button(parent, textvariable=tvar, command=swaptext) 11 | my_button.pack() 12 | 13 | 14 | parent.mainloop() 15 | -------------------------------------------------------------------------------- /Chapter08/tk_default_font_example.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter.font import nametofont 3 | 4 | root = tk.Tk() 5 | 6 | # Get and adjust default font 7 | default_font = nametofont('TkDefaultFont') 8 | default_font.config(family='Helvetica', size=32) 9 | 10 | # Display a label 11 | tk.Label(text='Feeling Groovy').pack() 12 | 13 | root.mainloop() 14 | -------------------------------------------------------------------------------- /Chapter08/font_lister.py: -------------------------------------------------------------------------------- 1 | from tkinter import Tk 2 | from tkinter.font import names, nametofont 3 | 4 | r = Tk() 5 | for fontname in names(): 6 | font = nametofont(fontname) 7 | print('{}:\t {} {} {} {}'.format( 8 | fontname, 9 | font['family'], 10 | font['size'], 11 | font['weight'], 12 | font['slant'] 13 | )) 14 | -------------------------------------------------------------------------------- /Chapter11/ftp_retr_demo.py: -------------------------------------------------------------------------------- 1 | from ftplib import FTP 2 | from os.path import join 3 | 4 | filename = 'raytux.jpg' 5 | path = '/pub/ibiblio/logos/penguins' 6 | destination = open(filename, 'wb') 7 | with FTP('ftp.nluug.nl', 'anonymous') as ftp: 8 | ftp.retrbinary( 9 | 'RETR {}'.format(join(path, filename)), 10 | destination.write) 11 | destination.close() 12 | -------------------------------------------------------------------------------- /Chapter09/unittest_demo/test_mycalc_no_unittest.py: -------------------------------------------------------------------------------- 1 | from mycalc import MyCalc 2 | 3 | mc1 = MyCalc(1, 100) 4 | mc2 = MyCalc(10, 4) 5 | 6 | try: 7 | assert mc1.add() == 101, "Test of add() failed." 8 | assert mc2.mod_divide() == (2, 2), "Test of mod_divide() failed." 9 | except AssertionError as e: 10 | print("Test failed: ", e) 11 | else: 12 | print("Tests succeeded!") 13 | -------------------------------------------------------------------------------- /Chapter09/unittest_demo/test_mycalc_badly.py: -------------------------------------------------------------------------------- 1 | from mycalc import MyCalc 2 | import unittest 3 | 4 | 5 | class TestMyCalc(unittest.TestCase): 6 | 7 | def test_add(self): 8 | mc = MyCalc(1, 10) 9 | assert mc.add() == 11 10 | 11 | # much better error output 12 | self.assertEqual(mc.add(), 12) 13 | 14 | if __name__ == '__main__': 15 | unittest.main() 16 | -------------------------------------------------------------------------------- /Chapter04/FiveCharEntry.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | 4 | root = tk.Tk() 5 | 6 | def has_five_or_less_chars(string): 7 | return len(string) <= 5 8 | 9 | wrapped_function = root.register(has_five_or_less_chars) 10 | vcmd = (wrapped_function, '%P') 11 | five_char_input = ttk.Entry(root, validate='key', validatecommand=vcmd) 12 | 13 | five_char_input.pack() 14 | root.mainloop() 15 | -------------------------------------------------------------------------------- /Chapter11/basic_ftp_server.py: -------------------------------------------------------------------------------- 1 | from pyftpdlib.authorizers import DummyAuthorizer 2 | from pyftpdlib.handlers import FTPHandler 3 | from pyftpdlib.servers import FTPServer 4 | 5 | auth = DummyAuthorizer() 6 | auth.add_user('test', 'test', '.', perm='elrw') 7 | 8 | handler = FTPHandler 9 | handler.authorizer = auth 10 | 11 | address = ('127.0.0.1', 2100) 12 | server = FTPServer(address, handler) 13 | 14 | server.serve_forever() 15 | -------------------------------------------------------------------------------- /Chapter06/messagebox_demo.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import messagebox 3 | 4 | see_more = messagebox.askyesno( 5 | title='See more?', 6 | message='Would you like to see another box?', 7 | detail='Click NO to quit' 8 | ) 9 | 10 | if not see_more: 11 | exit() 12 | 13 | messagebox.showinfo( 14 | title='You got it', 15 | message="Ok, here's another dialog.", 16 | detail='Hope you like it!' 17 | ) 18 | -------------------------------------------------------------------------------- /Chapter08/image_scope_demo.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | 3 | class App(tk.Tk): 4 | def __init__(self): 5 | super().__init__() 6 | tk.Label(self, image=tk.PhotoImage(file='smile.gif')).pack() 7 | smile = tk.PhotoImage(file='smile.gif') 8 | tk.Label(self, image=smile).pack() 9 | self.smile = tk.PhotoImage(file='smile.gif') 10 | tk.Label(self, image=self.smile).pack() 11 | 12 | App().mainloop() 13 | -------------------------------------------------------------------------------- /Chapter14/calldemoSignalSlot1.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoSignalSlot1 import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.show() 13 | 14 | if __name__=="__main__": 15 | app = QApplication(sys.argv) 16 | w = MyForm() 17 | w.show() 18 | sys.exit(app.exec_()) 19 | -------------------------------------------------------------------------------- /Chapter06/filedialog_demo.py: -------------------------------------------------------------------------------- 1 | from tkinter import filedialog 2 | 3 | source = filedialog.askopenfile( 4 | mode='r', 5 | title='Select a CSV file to copy', 6 | filetypes=[('CSV', '*.csv *.CSV')]) 7 | 8 | if not source: 9 | exit() 10 | 11 | destination = filedialog.asksaveasfile( 12 | mode='w', 13 | title='Select a destination file', 14 | defaultextension='.csv', 15 | filetypes=[('CSV', '*.csv *.CSV')]) 16 | 17 | destination.write(source.read()) 18 | source.close() 19 | destination.close() 20 | -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/sql/populate_db.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO lab_techs VALUES 2 | (4291, 'J Simms'), 3 | (4319, 'P Taylor'), 4 | (4478, 'Q Murphy'), 5 | (5607, 'L Taniff') 6 | ; 7 | 8 | INSERT INTO labs VALUES 9 | ('A'), ('B'), ('C'), ('D'), ('E'); 10 | 11 | INSERT INTO plots (SELECT labs.id, plotnums.plot 12 | FROM labs, (SELECT generate_series(1, 20) plot) AS plotnums); 13 | 14 | UPDATE plots SET current_seed_sample= 15 | (CASE WHEN plot % 4 = 1 THEN 'AXM477' 16 | WHEN plot % 4 = 2 THEN 'AXM478' 17 | WHEN plot % 4 = 3 THEN 'AXM479' 18 | WHEN plot % 4 = 0 THEN 'AXM480' 19 | ELSE '' END) 20 | ; 21 | -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/sql/populate_db.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO lab_techs VALUES 2 | (4291, 'J Simms'), 3 | (4319, 'P Taylor'), 4 | (4478, 'Q Murphy'), 5 | (5607, 'L Taniff') 6 | ; 7 | 8 | INSERT INTO labs VALUES 9 | ('A'), ('B'), ('C'), ('D'), ('E'); 10 | 11 | INSERT INTO plots (SELECT labs.id, plotnums.plot 12 | FROM labs, (SELECT generate_series(1, 20) plot) AS plotnums); 13 | 14 | UPDATE plots SET current_seed_sample= 15 | (CASE WHEN plot % 4 = 1 THEN 'AXM477' 16 | WHEN plot % 4 = 2 THEN 'AXM478' 17 | WHEN plot % 4 = 3 THEN 'AXM479' 18 | WHEN plot % 4 = 0 THEN 'AXM480' 19 | ELSE '' END) 20 | ; 21 | -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/sql/populate_db.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO lab_techs VALUES 2 | (4291, 'J Simms'), 3 | (4319, 'P Taylor'), 4 | (4478, 'Q Murphy'), 5 | (5607, 'L Taniff') 6 | ; 7 | 8 | INSERT INTO labs VALUES 9 | ('A'), ('B'), ('C'), ('D'), ('E'); 10 | 11 | INSERT INTO plots (SELECT labs.id, plotnums.plot 12 | FROM labs, (SELECT generate_series(1, 20) plot) AS plotnums); 13 | 14 | UPDATE plots SET current_seed_sample= 15 | (CASE WHEN plot % 4 = 1 THEN 'AXM477' 16 | WHEN plot % 4 = 2 THEN 'AXM478' 17 | WHEN plot % 4 = 3 THEN 'AXM479' 18 | WHEN plot % 4 = 0 THEN 'AXM480' 19 | ELSE '' END) 20 | ; 21 | -------------------------------------------------------------------------------- /Chapter03/text_widget_example.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | 3 | 4 | parent = tk.Tk() 5 | # create the widget. Make sure to save a reference. 6 | mytext = tk.Text(parent) 7 | 8 | # insert a string at the beginning 9 | mytext.insert('1.0', "I love my text widget!") 10 | 11 | # insert a string into the current text 12 | mytext.insert('1.2', 'REALLY ') 13 | 14 | # get the whole string 15 | mytext.get('1.0', tk.END) 16 | 17 | # delete the last character. 18 | # Note that there is always a newline character 19 | # at the end of the input, so we backup 2 chars. 20 | mytext.delete('end - 2 chars') 21 | 22 | 23 | mytext.pack() 24 | parent.mainloop() 25 | -------------------------------------------------------------------------------- /Chapter13/callLineEdit.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoLineEdit import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.ButtonClickMe.clicked.connect(self.dispmessage) 13 | self.show() 14 | 15 | def dispmessage(self): 16 | self.ui.labelResponse.setText("Hello "+self.ui.lineEditName.text()) 17 | 18 | if __name__=="__main__": 19 | app = QApplication(sys.argv) 20 | w = MyForm() 21 | w.show() 22 | sys.exit(app.exec_()) 23 | -------------------------------------------------------------------------------- /Chapter14/callProgressBar.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoProgressBar import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.pushButtonStart.clicked.connect(self.updateBar) 13 | self.show() 14 | 15 | def updateBar(self): 16 | x = 0 17 | while x < 100: 18 | x += 0.0001 19 | self.ui.progressBar.setValue(x) 20 | 21 | if __name__=="__main__": 22 | app = QApplication(sys.argv) 23 | w = MyForm() 24 | w.show() 25 | sys.exit(app.exec_()) 26 | -------------------------------------------------------------------------------- /Chapter14/callListWidget1.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoListWidget1 import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.listWidgetDiagnosis.itemClicked.connect(self.dispSelectedTest) 13 | self.show() 14 | 15 | def dispSelectedTest(self): 16 | self.ui.labelTest.setText("You have selected "+self.ui.listWidgetDiagnosis.currentItem().text()) 17 | 18 | if __name__=="__main__": 19 | app = QApplication(sys.argv) 20 | w = MyForm() 21 | w.show() 22 | sys.exit(app.exec_()) 23 | -------------------------------------------------------------------------------- /Chapter20/callMouseTrack.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | from PyQt5.QtWidgets import QDialog, QApplication 3 | from demoMousetrack import * 4 | 5 | class MyForm(QDialog): 6 | def __init__(self): 7 | super().__init__() 8 | self.ui = Ui_Dialog() 9 | self.setMouseTracking(True) 10 | self.ui.setupUi(self) 11 | self.show() 12 | 13 | def mouseMoveEvent(self, event): 14 | x = event.x() 15 | y = event.y() 16 | text = "x: {0}, y: {1}".format(x, y) 17 | self.ui.label.setText(text) 18 | 19 | if __name__=="__main__": 20 | app = QApplication(sys.argv) 21 | w = MyForm() 22 | w.show() 23 | sys.exit(app.exec_()) 24 | -------------------------------------------------------------------------------- /Chapter08/tags_demo.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | 3 | text = tk.Text(width=50, height=20, bg='black', fg='lightgreen') 4 | text.pack() 5 | text.tag_configure('prompt', foreground='magenta') 6 | text.tag_configure('output', foreground='yellow') 7 | text.insert('end', '>>> ', ('prompt',)) 8 | 9 | def on_return(*args): 10 | cmd = text.get('prompt.last', 'end').strip() 11 | if cmd: 12 | try: 13 | output = str(eval(cmd)) 14 | except Exception as e: 15 | output = str(e) 16 | text.insert('end', '\n' + output, ('output',)) 17 | text.insert('end', '\n>>> ', ('prompt',)) 18 | return 'break' 19 | 20 | 21 | text.bind('', on_return) 22 | text.mainloop() 23 | -------------------------------------------------------------------------------- /Chapter16/callFontDialog.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication, QFontDialog 4 | 5 | 6 | from demoFontDialog import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.ui.pushButtonFont.clicked.connect(self.changefont) 14 | self.show() 15 | 16 | def changefont(self): 17 | font, ok = QFontDialog.getFont() 18 | if ok: 19 | self.ui.textEdit.setFont(font) 20 | 21 | if __name__=="__main__": 22 | app = QApplication(sys.argv) 23 | w = MyForm() 24 | w.show() 25 | sys.exit(app.exec_()) 26 | 27 | -------------------------------------------------------------------------------- /Chapter11/urllib_examples.py: -------------------------------------------------------------------------------- 1 | from urllib.request import urlopen 2 | 3 | # Basic GET request and response examination 4 | response = urlopen('http://packtpub.com') 5 | print(response.getheader('Content-Type')) 6 | print(response.getheader('Server')) 7 | print(response.status) 8 | print(response.reason) 9 | 10 | html = response.read() 11 | print(html[:15]) 12 | print(html.decode('utf-8')[:15]) 13 | 14 | # Basic POST request with data 15 | response = urlopen('http://duckduckgo.com', data=b'q=tkinter') 16 | 17 | from urllib.parse import urlencode 18 | data = {'q': 'tkinter, python', 'ko': '-2', 'kz': '-1'} 19 | print(urlencode(data)) 20 | 21 | response = urlopen('http://duckduckgo.com', data=urlencode(data).encode()) 22 | -------------------------------------------------------------------------------- /Chapter04/MixinExample.py: -------------------------------------------------------------------------------- 1 | """This example shows the use of a mixin class""" 2 | 3 | class Displayer(): 4 | 5 | def display(self, message): 6 | print(message) 7 | 8 | class LoggerMixin(): 9 | 10 | def log(self, message, filename='logfile.txt'): 11 | with open(filename, 'a') as fh: 12 | fh.write(message) 13 | 14 | def display(self, message): 15 | super().display(message) 16 | self.log(message) 17 | 18 | class MySubClass(LoggerMixin, Displayer): 19 | 20 | def log(self, message): 21 | super().log(message, filename='subclasslog.txt') 22 | 23 | 24 | subclass = MySubClass() 25 | subclass.display("This string will be shown and logged in subclasslog.txt.") 26 | -------------------------------------------------------------------------------- /Chapter14/callComboBox.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoComboBox import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.comboBoxAccountType.currentIndexChanged.connect(self.dispAccountType) 13 | self.show() 14 | 15 | def dispAccountType(self): 16 | self.ui.labelAccountType.setText("You have selected "+self.ui.comboBoxAccountType.itemText(self.ui.comboBoxAccountType.currentIndex())) 17 | 18 | if __name__=="__main__": 19 | app = QApplication(sys.argv) 20 | w = MyForm() 21 | w.show() 22 | sys.exit(app.exec_()) 23 | -------------------------------------------------------------------------------- /Chapter21/demoGraphicsView.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 457 10 | 225 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 40 20 | 20 21 | 371 22 | 181 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter14/callListWidget3.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoListWidget3 import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.pushButtonAdd.clicked.connect(self.addlist) 13 | self.show() 14 | 15 | def addlist(self): 16 | self.ui.listWidgetSelectedItems.addItem(self.ui.lineEditFoodItem.text()) 17 | self.ui.lineEditFoodItem.setText('') 18 | self.ui.lineEditFoodItem.setFocus() 19 | 20 | if __name__=="__main__": 21 | app = QApplication(sys.argv) 22 | w = MyForm() 23 | w.show() 24 | sys.exit(app.exec_()) 25 | -------------------------------------------------------------------------------- /Chapter21/callGraphicsView.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication, QGraphicsScene, QGraphicsPixmapItem 4 | from PyQt5.QtGui import QPixmap 5 | from demoGraphicsView import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.scene = QGraphicsScene(self) 13 | pixmap= QtGui.QPixmap() 14 | pixmap.load("bintupic.jpg") 15 | item=QGraphicsPixmapItem(pixmap) 16 | self.scene.addItem(item) 17 | self.ui.graphicsView.setScene(self.scene) 18 | 19 | if __name__=="__main__": 20 | app = QApplication(sys.argv) 21 | myapp = MyForm() 22 | myapp.show() 23 | sys.exit(app.exec_()) 24 | -------------------------------------------------------------------------------- /Chapter04/FiveCharEntry2.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | 4 | class FiveCharEntry2(ttk.Entry): 5 | """An Entry that truncates to five characters on exit.""" 6 | 7 | def __init__(self, parent, *args, **kwargs): 8 | super().__init__(parent, *args, **kwargs) 9 | self.config( 10 | validate='focusout', 11 | validatecommand=(self.register(self._validate), '%P'), 12 | invalidcommand=(self.register(self._on_invalid),) 13 | ) 14 | 15 | def _validate(self, proposed_value): 16 | return len(proposed_value) <= 5 17 | 18 | def _on_invalid(self): 19 | self.delete(5, tk.END) 20 | 21 | 22 | if __name__ == '__main__': 23 | root = tk.Tk() 24 | entry = FiveCharEntry2(root) 25 | entry.pack() 26 | tk.Entry(root).pack() 27 | root.mainloop() 28 | -------------------------------------------------------------------------------- /Chapter09/unittest_demo/mycalc.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | class MyCalc: 4 | 5 | def __init__(self, a, b): 6 | self.a = a 7 | self.b = b 8 | 9 | def add(self): 10 | return self.a + self.b 11 | 12 | def mod_divide(self): 13 | if self.b == 0: 14 | raise ValueError("Cannot divide by zero") 15 | return (int(self.a / self.b), self.a % self.b) 16 | 17 | def mod_divide2(self): 18 | if type(self.a) is not int or type(self.b) is not int: 19 | raise ValueError("Method only valid for ints") 20 | if self.b == 0: 21 | raise ValueError("Cannot divide by zero") 22 | return (self.a // self.b, self.a % self.b) 23 | 24 | def rand_between(self): 25 | return ( 26 | (random.random() * abs(self.a - self.b)) + 27 | min(self.a, self.b)) 28 | -------------------------------------------------------------------------------- /Chapter14/callFontComboBox.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoFontComboBox import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | myFont=QtGui.QFont(self.ui.fontComboBox.itemText(self.ui.fontComboBox.currentIndex()),15) 13 | self.ui.textEdit.setFont(myFont) 14 | self.ui.fontComboBox.currentFontChanged.connect(self.changeFont) 15 | self.show() 16 | 17 | def changeFont(self): 18 | myFont=QtGui.QFont(self.ui.fontComboBox.itemText(self.ui.fontComboBox.currentIndex()),15) 19 | self.ui.textEdit.setFont(myFont) 20 | if __name__=="__main__": 21 | app = QApplication(sys.argv) 22 | w = MyForm() 23 | w.show() 24 | sys.exit(app.exec_()) 25 | -------------------------------------------------------------------------------- /Chapter14/callListWidget2.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoListWidget2 import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.listWidgetDiagnosis.itemSelectionChanged.connect(self.dispSelectedTest) 13 | self.show() 14 | 15 | def dispSelectedTest(self): 16 | self.ui.listWidgetSelectedTests.clear() 17 | items = self.ui.listWidgetDiagnosis.selectedItems() 18 | x=[] 19 | for i in list(items): 20 | self.ui.listWidgetSelectedTests.addItem(i.text()) 21 | x.append(str(i.text())) 22 | 23 | if __name__=="__main__": 24 | app = QApplication(sys.argv) 25 | w = MyForm() 26 | w.show() 27 | sys.exit(app.exec_()) 28 | -------------------------------------------------------------------------------- /Chapter15/callLineEditClass.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from LineEditClass import * 6 | 7 | class Student: 8 | name = "" 9 | 10 | def __init__(self, name): 11 | self.name = name 12 | 13 | def printName(self): 14 | return self.name 15 | 16 | class MyForm(QDialog): 17 | def __init__(self): 18 | super().__init__() 19 | self.ui = Ui_Dialog() 20 | self.ui.setupUi(self) 21 | self.ui.ButtonClickMe.clicked.connect(self.dispmessage) 22 | self.show() 23 | 24 | def dispmessage(self): 25 | studentObj=Student(self.ui.lineEditName.text()) 26 | self.ui.labelResponse.setText("Hello "+studentObj.printName()) 27 | 28 | if __name__=="__main__": 29 | app = QApplication(sys.argv) 30 | w = MyForm() 31 | w.show() 32 | sys.exit(app.exec_()) 33 | -------------------------------------------------------------------------------- /Chapter21/callAnimation1.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from PyQt5.QtCore import QRect, QPropertyAnimation 5 | 6 | from demoAnimation1 import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.ui.pushButtonMoveDown.clicked.connect(self.startAnimation) 14 | self.show() 15 | 16 | def startAnimation(self): 17 | self.anim = QPropertyAnimation(self.ui.labelPic, b"geometry") 18 | self.anim.setDuration(10000) 19 | self.anim.setStartValue(QRect(160, 70, 80, 80)) 20 | self.anim.setEndValue(QRect(160, 70, 220, 220)) 21 | self.anim.start() 22 | 23 | if __name__=="__main__": 24 | app = QApplication(sys.argv) 25 | w = MyForm() 26 | w.show() 27 | sys.exit(app.exec_()) 28 | -------------------------------------------------------------------------------- /Chapter19/callDatabase.pyw: -------------------------------------------------------------------------------- 1 | import sqlite3, sys 2 | from PyQt5.QtWidgets import QDialog, QApplication 3 | from sqlite3 import Error 4 | 5 | from demoDatabase import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.pushButtonCreateDB.clicked.connect(self.createDatabase) 13 | self.show() 14 | 15 | def createDatabase(self): 16 | try: 17 | conn = sqlite3.connect(self.ui.lineEditDBName.text()+".db") 18 | self.ui.labelResponse.setText("Database is created") 19 | except Error as e: 20 | self.ui.labelResponse.setText("Some error has occurred") 21 | finally: 22 | conn.close() 23 | 24 | if __name__=="__main__": 25 | app = QApplication(sys.argv) 26 | w = MyForm() 27 | w.show() 28 | sys.exit(app.exec_()) 29 | -------------------------------------------------------------------------------- /Chapter21/demoGraphicsView.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoGraphicsView.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(457, 225) 15 | self.graphicsView = QtWidgets.QGraphicsView(Dialog) 16 | self.graphicsView.setGeometry(QtCore.QRect(40, 20, 371, 181)) 17 | self.graphicsView.setObjectName("graphicsView") 18 | 19 | self.retranslateUi(Dialog) 20 | QtCore.QMetaObject.connectSlotsByName(Dialog) 21 | 22 | def retranslateUi(self, Dialog): 23 | _translate = QtCore.QCoreApplication.translate 24 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 25 | 26 | -------------------------------------------------------------------------------- /Chapter22/callGoogleMap.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtCore import QUrl 4 | from PyQt5.QtWidgets import QApplication, QDialog 5 | from PyQt5.QtWebEngineWidgets import QWebEngineView 6 | 7 | from showGoogleMap import * 8 | 9 | class MyForm(QDialog): 10 | def __init__(self): 11 | super().__init__() 12 | self.ui = Ui_Dialog() 13 | self.ui.setupUi(self) 14 | self.ui.pushButtonShowMap.clicked.connect(self.dispSite) 15 | self.show() 16 | 17 | 18 | def dispSite(self): 19 | lng = float(self.ui.lineEditLongitude.text()) 20 | lat = float(self.ui.lineEditLatitude.text()) 21 | URL="https://www.google.com/maps/@"+self.ui.lineEditLatitude.text()+","+self.ui.lineEditLongitude.text()+",9z" 22 | self.ui.widget.load(QUrl(URL)) 23 | 24 | if __name__=="__main__": 25 | app = QApplication(sys.argv) 26 | w = MyForm() 27 | w.show() 28 | sys.exit(app.exec_()) 29 | -------------------------------------------------------------------------------- /Chapter16/callInputDialog.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication, QInputDialog 4 | 5 | from demoInputDialog import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.pushButtonCountry.clicked.connect(self.dispmessage) 13 | self.show() 14 | 15 | def dispmessage(self): 16 | countries = ("Albania", "Algeria", "Andorra", "Angola", "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan") 17 | countryName, ok = QInputDialog.getItem(self, "Input Dialog", "List of countries", countries, 0, False) 18 | if ok and countryName: 19 | self.ui.lineEditCountry.setText(countryName) 20 | 21 | if __name__=="__main__": 22 | app = QApplication(sys.argv) 23 | w = MyForm() 24 | w.show() 25 | sys.exit(app.exec_()) 26 | 27 | -------------------------------------------------------------------------------- /Chapter20/demoDrawDot.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 402 10 | 259 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 10 21 | 361 22 | 51 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | Click the mouse where you want to display a dot 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter21/callAnimation3.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from PyQt5.QtCore import QRect, QPropertyAnimation 5 | 6 | from demoAnimation3 import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.ui.pushButtonBounce.clicked.connect(self.startAnimation) 14 | self.show() 15 | 16 | def startAnimation(self): 17 | self.anim = QPropertyAnimation(self.ui.labelPic, b"geometry") 18 | self.anim.setDuration(10000) 19 | self.anim.setKeyValueAt(0, QRect(0, 0, 100, 80)); 20 | self.anim.setKeyValueAt(0.8, QRect(160, 160, 200, 180)); 21 | self.anim.setKeyValueAt(1, QRect(400, 0, 100, 80)); 22 | self.anim.start() 23 | 24 | if __name__=="__main__": 25 | app = QApplication(sys.argv) 26 | w = MyForm() 27 | w.show() 28 | sys.exit(app.exec_()) 29 | -------------------------------------------------------------------------------- /Chapter20/demoDrawLine.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 500 10 | 340 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 10 21 | 461 22 | 51 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | Click the mouse and drag it to draw the line of desired size 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter20/demoDrawCircle.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 500 10 | 340 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 10 21 | 461 22 | 51 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | Click the mouse and drag it to draw the circle of desired size 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter20/demoDrawRectangle.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 500 10 | 340 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 10 21 | 461 22 | 51 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | Click the mouse and drag it to draw the rectangle of desired size 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter08/font_demo.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter.font import Font 3 | 4 | root = tk.Tk() 5 | 6 | # Fonts can be specified directly as a string 7 | # in the format "family size [style] [style] ..." 8 | # where "style" can be any of normal, bold, italic, underline, overstrike 9 | 10 | tk.Label(text="Direct font format", font="Times").pack() 11 | 12 | # Fonts can be specified as a tuple in the same order 13 | tk.Label( 14 | text="Tuple font format", 15 | font=('Droid sans', 15, 'overstrike') 16 | ).pack() 17 | 18 | # Fonts can use named fonts created via the Font class 19 | labelfont = Font(family='Courier', size=30, 20 | weight='bold', slant='roman', 21 | underline=False, overstrike=False) 22 | tk.Label(text='Using the Font class', font=labelfont).pack() 23 | 24 | def toggle_overstrike(): 25 | labelfont['overstrike'] = not labelfont['overstrike'] 26 | 27 | tk.Button(text='Toggle Overstrike', command=toggle_overstrike).pack() 28 | 29 | root.mainloop() 30 | -------------------------------------------------------------------------------- /Chapter12/simple_canvas_demo.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | 3 | root = tk.Tk() 4 | canvas = tk.Canvas(root, width=1024, height=768) 5 | canvas.pack() 6 | # configure canvas 7 | canvas.config(background='black') 8 | 9 | # draw a square 10 | canvas.create_rectangle(100, 100, 200, 200, fill='orange') 11 | canvas.create_rectangle((600, 100), (700, 200), fill='#FF8800') 12 | 13 | # draw an oval 14 | canvas.create_oval((350, 250), (450, 350), fill='blue') 15 | 16 | # draw a line 17 | canvas.create_line((100, 400), (400, 500), (700, 400), (100, 400), width=5, fill='red') 18 | 19 | # draw a polygon 20 | canvas.create_polygon((400, 150), (350, 300), (450, 300), fill='blue', smooth=True) 21 | 22 | # draw text 23 | canvas.create_text((400, 600), text='Smile!', fill='cyan', font='TkDefaultFont 64') 24 | # draw an image 25 | smiley = tk.PhotoImage(file='smile.gif') 26 | image_item = canvas.create_image((400, 300), image=smiley) 27 | canvas.tag_bind(image_item, '', lambda e: canvas.delete(image_item)) 28 | 29 | root.mainloop() 30 | -------------------------------------------------------------------------------- /Chapter16/callColorDialog.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication, QColorDialog 4 | from PyQt5.QtGui import QColor 5 | 6 | from demoColorDialog import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | col = QColor(0, 0, 0) 12 | self.ui = Ui_Dialog() 13 | self.ui.setupUi(self) 14 | self.ui.frameColor.setStyleSheet("QWidget { background-color: %s }" % col.name()) 15 | self.ui.pushButtonColor.clicked.connect(self.dispcolor) 16 | self.show() 17 | 18 | def dispcolor(self): 19 | col = QColorDialog.getColor() 20 | if col.isValid(): 21 | self.ui.frameColor.setStyleSheet("QWidget { background-color: %s }" % col.name()) 22 | self.ui.labelColor.setText("You have selected the color with code: " + str(col.name())) 23 | 24 | if __name__=="__main__": 25 | app = QApplication(sys.argv) 26 | w = MyForm() 27 | w.show() 28 | sys.exit(app.exec_()) 29 | 30 | -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry/README.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | ABQ Data Entry Application 3 | ============================ 4 | 5 | Description 6 | =========== 7 | 8 | This program provides a data entry form for ABQ Agrilabs laboratory data. 9 | 10 | Features 11 | -------- 12 | 13 | * Provides a validated entry form to ensure correct data 14 | * Stores data to ABQ-format CSV files 15 | * Auto-fills form fields whenever possible 16 | 17 | Authors 18 | ======= 19 | 20 | Alan D Moore, 2018 21 | 22 | Requirements 23 | ============ 24 | 25 | * Python 3 26 | * Tkinter 27 | 28 | Usage 29 | ===== 30 | 31 | To start the application, run:: 32 | 33 | python3 ABQ_Data_Entry/abq_data_entry.py 34 | 35 | 36 | General Notes 37 | ============= 38 | 39 | The CSV file will be saved to your current directory in the format "abq_data_record_CURRENTDATE.csv", where CURRENTDATE is today's date in ISO format. 40 | 41 | This program only appends to the CSV file. You should have a spreadsheet program installed in case you need to edit or check the file. 42 | -------------------------------------------------------------------------------- /Chapter06/ABQ_Data_Entry/README.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | ABQ Data Entry Application 3 | ============================ 4 | 5 | Description 6 | =========== 7 | 8 | This program provides a data entry form for ABQ Agrilabs laboratory data. 9 | 10 | Features 11 | -------- 12 | 13 | * Provides a validated entry form to ensure correct data 14 | * Stores data to ABQ-format CSV files 15 | * Auto-fills form fields whenever possible 16 | 17 | Authors 18 | ======= 19 | 20 | Alan D Moore, 2018 21 | 22 | Requirements 23 | ============ 24 | 25 | * Python 3 26 | * Tkinter 27 | 28 | Usage 29 | ===== 30 | 31 | To start the application, run:: 32 | 33 | python3 ABQ_Data_Entry/abq_data_entry.py 34 | 35 | 36 | General Notes 37 | ============= 38 | 39 | The CSV file will be saved to your current directory in the format "abq_data_record_CURRENTDATE.csv", where CURRENTDATE is today's date in ISO format. 40 | 41 | This program only appends to the CSV file. You should have a spreadsheet program installed in case you need to edit or check the file. 42 | -------------------------------------------------------------------------------- /Chapter07/ABQ_Data_Entry/README.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | ABQ Data Entry Application 3 | ============================ 4 | 5 | Description 6 | =========== 7 | 8 | This program provides a data entry form for ABQ Agrilabs laboratory data. 9 | 10 | Features 11 | -------- 12 | 13 | * Provides a validated entry form to ensure correct data 14 | * Stores data to ABQ-format CSV files 15 | * Auto-fills form fields whenever possible 16 | 17 | Authors 18 | ======= 19 | 20 | Alan D Moore, 2018 21 | 22 | Requirements 23 | ============ 24 | 25 | * Python 3 26 | * Tkinter 27 | 28 | Usage 29 | ===== 30 | 31 | To start the application, run:: 32 | 33 | python3 ABQ_Data_Entry/abq_data_entry.py 34 | 35 | 36 | General Notes 37 | ============= 38 | 39 | The CSV file will be saved to your current directory in the format "abq_data_record_CURRENTDATE.csv", where CURRENTDATE is today's date in ISO format. 40 | 41 | This program only appends to the CSV file. You should have a spreadsheet program installed in case you need to edit or check the file. 42 | -------------------------------------------------------------------------------- /Chapter08/ABQ_Data_Entry/README.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | ABQ Data Entry Application 3 | ============================ 4 | 5 | Description 6 | =========== 7 | 8 | This program provides a data entry form for ABQ Agrilabs laboratory data. 9 | 10 | Features 11 | -------- 12 | 13 | * Provides a validated entry form to ensure correct data 14 | * Stores data to ABQ-format CSV files 15 | * Auto-fills form fields whenever possible 16 | 17 | Authors 18 | ======= 19 | 20 | Alan D Moore, 2018 21 | 22 | Requirements 23 | ============ 24 | 25 | * Python 3 26 | * Tkinter 27 | 28 | Usage 29 | ===== 30 | 31 | To start the application, run:: 32 | 33 | python3 ABQ_Data_Entry/abq_data_entry.py 34 | 35 | 36 | General Notes 37 | ============= 38 | 39 | The CSV file will be saved to your current directory in the format "abq_data_record_CURRENTDATE.csv", where CURRENTDATE is today's date in ISO format. 40 | 41 | This program only appends to the CSV file. You should have a spreadsheet program installed in case you need to edit or check the file. 42 | -------------------------------------------------------------------------------- /Chapter09/ABQ_Data_Entry/README.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | ABQ Data Entry Application 3 | ============================ 4 | 5 | Description 6 | =========== 7 | 8 | This program provides a data entry form for ABQ Agrilabs laboratory data. 9 | 10 | Features 11 | -------- 12 | 13 | * Provides a validated entry form to ensure correct data 14 | * Stores data to ABQ-format CSV files 15 | * Auto-fills form fields whenever possible 16 | 17 | Authors 18 | ======= 19 | 20 | Alan D Moore, 2018 21 | 22 | Requirements 23 | ============ 24 | 25 | * Python 3 26 | * Tkinter 27 | 28 | Usage 29 | ===== 30 | 31 | To start the application, run:: 32 | 33 | python3 ABQ_Data_Entry/abq_data_entry.py 34 | 35 | 36 | General Notes 37 | ============= 38 | 39 | The CSV file will be saved to your current directory in the format "abq_data_record_CURRENTDATE.csv", where CURRENTDATE is today's date in ISO format. 40 | 41 | This program only appends to the CSV file. You should have a spreadsheet program installed in case you need to edit or check the file. 42 | -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/README.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | ABQ Data Entry Application 3 | ============================ 4 | 5 | Description 6 | =========== 7 | 8 | This program provides a data entry form for ABQ Agrilabs laboratory data. 9 | 10 | Features 11 | -------- 12 | 13 | * Provides a validated entry form to ensure correct data 14 | * Stores data to ABQ-format CSV files 15 | * Auto-fills form fields whenever possible 16 | 17 | Authors 18 | ======= 19 | 20 | Alan D Moore, 2018 21 | 22 | Requirements 23 | ============ 24 | 25 | * Python 3 26 | * Tkinter 27 | 28 | Usage 29 | ===== 30 | 31 | To start the application, run:: 32 | 33 | python3 ABQ_Data_Entry/abq_data_entry.py 34 | 35 | 36 | General Notes 37 | ============= 38 | 39 | The CSV file will be saved to your current directory in the format "abq_data_record_CURRENTDATE.csv", where CURRENTDATE is today's date in ISO format. 40 | 41 | This program only appends to the CSV file. You should have a spreadsheet program installed in case you need to edit or check the file. 42 | -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/README.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | ABQ Data Entry Application 3 | ============================ 4 | 5 | Description 6 | =========== 7 | 8 | This program provides a data entry form for ABQ Agrilabs laboratory data. 9 | 10 | Features 11 | -------- 12 | 13 | * Provides a validated entry form to ensure correct data 14 | * Stores data to ABQ-format CSV files 15 | * Auto-fills form fields whenever possible 16 | 17 | Authors 18 | ======= 19 | 20 | Alan D Moore, 2018 21 | 22 | Requirements 23 | ============ 24 | 25 | * Python 3 26 | * Tkinter 27 | 28 | Usage 29 | ===== 30 | 31 | To start the application, run:: 32 | 33 | python3 ABQ_Data_Entry/abq_data_entry.py 34 | 35 | 36 | General Notes 37 | ============= 38 | 39 | The CSV file will be saved to your current directory in the format "abq_data_record_CURRENTDATE.csv", where CURRENTDATE is today's date in ISO format. 40 | 41 | This program only appends to the CSV file. You should have a spreadsheet program installed in case you need to edit or check the file. 42 | -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/README.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | ABQ Data Entry Application 3 | ============================ 4 | 5 | Description 6 | =========== 7 | 8 | This program provides a data entry form for ABQ Agrilabs laboratory data. 9 | 10 | Features 11 | -------- 12 | 13 | * Provides a validated entry form to ensure correct data 14 | * Stores data to ABQ-format CSV files 15 | * Auto-fills form fields whenever possible 16 | 17 | Authors 18 | ======= 19 | 20 | Alan D Moore, 2018 21 | 22 | Requirements 23 | ============ 24 | 25 | * Python 3 26 | * Tkinter 27 | 28 | Usage 29 | ===== 30 | 31 | To start the application, run:: 32 | 33 | python3 ABQ_Data_Entry/abq_data_entry.py 34 | 35 | 36 | General Notes 37 | ============= 38 | 39 | The CSV file will be saved to your current directory in the format "abq_data_record_CURRENTDATE.csv", where CURRENTDATE is today's date in ISO format. 40 | 41 | This program only appends to the CSV file. You should have a spreadsheet program installed in case you need to edit or check the file. 42 | -------------------------------------------------------------------------------- /Chapter20/callDrawDot.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from PyQt5.QtGui import QPainter, QPen 5 | from PyQt5.QtCore import Qt 6 | from demoDrawDot import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.pos1 = [0,0] 14 | self.show() 15 | 16 | def paintEvent(self, event): 17 | qp = QPainter() 18 | qp.begin(self) 19 | pen = QPen(Qt.black, 5) 20 | qp.setPen(pen) 21 | qp.drawPoint(self.pos1[0], self.pos1[1]) 22 | qp.end() 23 | 24 | def mousePressEvent(self, event): 25 | if event.buttons() & QtCore.Qt.LeftButton: 26 | self.pos1[0], self.pos1[1] = event.pos().x(), event.pos().y() 27 | self.update() 28 | 29 | if __name__=="__main__": 30 | app = QApplication(sys.argv) 31 | w = MyForm() 32 | w.show() 33 | sys.exit(app.exec_()) 34 | -------------------------------------------------------------------------------- /Chapter20/callMouseClickCoordinates.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from demoMouseClicks import * 5 | 6 | class MyForm(QDialog): 7 | def __init__(self): 8 | super().__init__() 9 | self.ui = Ui_Dialog() 10 | self.ui.setupUi(self) 11 | self.show() 12 | 13 | def mousePressEvent(self, event): 14 | if event.buttons() & QtCore.Qt.LeftButton: 15 | x = event.x() 16 | y = event.y() 17 | text = "x: {0}, y: {1}".format(x, y) 18 | self.ui.labelPress.setText('Mouse button pressed at '+text) 19 | 20 | def mouseReleaseEvent(self, event): 21 | x = event.x() 22 | y = event.y() 23 | text = "x: {0}, y: {1}".format(x, y) 24 | self.ui.labelRelease.setText('Mouse button released at '+text) 25 | self.update() 26 | 27 | if __name__=="__main__": 28 | app = QApplication(sys.argv) 29 | w = MyForm() 30 | w.show() 31 | sys.exit(app.exec_()) 32 | -------------------------------------------------------------------------------- /Chapter15/callStudentClass.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoStudentClass import * 6 | 7 | class Student: 8 | name = "" 9 | code = "" 10 | 11 | def __init__(self, code, name): 12 | self.code = code 13 | self.name = name 14 | 15 | def getCode(self): 16 | return self.code 17 | 18 | def getName(self): 19 | return self.name 20 | 21 | class MyForm(QDialog): 22 | def __init__(self): 23 | super().__init__() 24 | self.ui = Ui_Dialog() 25 | self.ui.setupUi(self) 26 | self.ui.ButtonClickMe.clicked.connect(self.dispmessage) 27 | self.show() 28 | 29 | def dispmessage(self): 30 | studentObj=Student(self.ui.lineEditCode.text(), self.ui.lineEditName.text()) 31 | self.ui.labelResponse.setText("Code: "+studentObj.getCode()+", Name:"+studentObj.getName()) 32 | 33 | if __name__=="__main__": 34 | app = QApplication(sys.argv) 35 | w = MyForm() 36 | w.show() 37 | sys.exit(app.exec_()) 38 | -------------------------------------------------------------------------------- /Chapter11/requests_example.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | # Make a simple GET request 4 | 5 | response = requests.request('GET', 'http://www.alandmoore.com/') 6 | print(response) 7 | 8 | response = requests.get('http://www.alandmoore.com') 9 | print(response) 10 | 11 | # Make a POST with data 12 | response = requests.post( 13 | 'http://duckduckgo.com', 14 | data={'q': 'tkinter', 'ko': '-2', 'kz': '-1'}) 15 | 16 | print(response) 17 | 18 | 19 | # Sessions 20 | 21 | s = requests.session() 22 | 23 | # Assume this is a valid authentication service that returns an auth token 24 | s.post('http://example.com/login', data={'u': 'test', 'p': 'test'}) 25 | # Now we would have an auth token 26 | response = s.get( 27 | 'http://example.com/protected_content' 28 | ) 29 | # Our token cookie would be listed here 30 | print(s.cookies.items()) 31 | 32 | 33 | # Response objects 34 | 35 | r = requests.get('http://www.alandmoore.com') 36 | print(r.headers) 37 | 38 | r = requests.get('http://www.example.com/does-not-exist') 39 | r.status_code 40 | 41 | r.raise_for_status() 42 | -------------------------------------------------------------------------------- /Chapter08/image_viewer_demo.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import filedialog 3 | from PIL import Image, ImageTk # this is pillow 4 | 5 | 6 | class PictureViewer(tk.Tk): 7 | 8 | def __init__(self, *args, **kwargs): 9 | super().__init__(*args, **kwargs) 10 | 11 | self.image_display = tk.Label(self) 12 | self.image_display.pack(expand=1, fill='both') 13 | self.photoimage = None 14 | button = tk.Button(self, text='Select image', 15 | command=self.choose_file) 16 | button.pack() 17 | 18 | def choose_file(self): 19 | filename = filedialog.askopenfilename( 20 | filetypes=( 21 | ('PNG files', '*.png *.PNG'), 22 | ('JPEG files', '*.jpg *.jpeg *.JPG *.JPEG'), 23 | ('GIF files', '*.gif *.GIF') 24 | )) 25 | image = Image.open(filename) 26 | self.photoimage = ImageTk.PhotoImage(image) 27 | self.image_display.config(image=self.photoimage) 28 | 29 | 30 | app = PictureViewer() 31 | app.mainloop() 32 | -------------------------------------------------------------------------------- /Chapter13/callRadioButton1.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoRadioButton1 import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.radioButtonFirstClass.toggled.connect(self.dispFare) 13 | self.ui.radioButtonBusinessClass.toggled.connect(self.dispFare) 14 | self.ui.radioButtonEconomyClass.toggled.connect(self.dispFare) 15 | self.show() 16 | 17 | def dispFare(self): 18 | fare=0 19 | if self.ui.radioButtonFirstClass.isChecked()==True: 20 | fare=150 21 | if self.ui.radioButtonBusinessClass.isChecked()==True: 22 | fare=125 23 | if self.ui.radioButtonEconomyClass.isChecked()==True: 24 | fare=100 25 | self.ui.labelFare.setText("Air Fare is "+str(fare)) 26 | 27 | if __name__=="__main__": 28 | app = QApplication(sys.argv) 29 | w = MyForm() 30 | w.show() 31 | sys.exit(app.exec_()) 32 | -------------------------------------------------------------------------------- /Chapter11/sample_http_server.py: -------------------------------------------------------------------------------- 1 | from http.server import HTTPServer, BaseHTTPRequestHandler 2 | 3 | 4 | class TestHandler(BaseHTTPRequestHandler): 5 | 6 | def _print_request_data(self): 7 | content_length = self.headers['Content-Length'] 8 | print("Content-length: {}".format(content_length)) 9 | data = self.rfile.read(int(content_length)) 10 | print(data.decode('utf-8')) 11 | 12 | def _send_200(self): 13 | self.send_response(200) 14 | self.send_header('Content-type', 'text/html') 15 | self.end_headers() 16 | 17 | def do_POST(self, *args, **kwargs): 18 | print('POST request received') 19 | self._print_request_data() 20 | self._send_200() 21 | 22 | def do_PUT(self, *args, **kwargs): 23 | print("PUT request received") 24 | self._print_request_data() 25 | self._send_200() 26 | 27 | 28 | def run(server_class=HTTPServer, handler_class=TestHandler): 29 | server_address = ('', 8000) 30 | httpd = server_class(server_address, handler_class) 31 | httpd.serve_forever() 32 | 33 | run() 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Chapter20/callDrawLine.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from PyQt5.QtGui import QPainter 5 | 6 | from demoDrawLine import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.pos1 = [0,0] 14 | self.pos2 = [0,0] 15 | self.show() 16 | 17 | def paintEvent(self, event): 18 | qp = QPainter() 19 | qp.begin(self) 20 | qp.drawLine(self.pos1[0], self.pos1[1], self.pos2[0], self.pos2[1]) 21 | qp.end() 22 | 23 | def mousePressEvent(self, event): 24 | if event.buttons() & QtCore.Qt.LeftButton: 25 | self.pos1[0], self.pos1[1] = event.pos().x(), event.pos().y() 26 | 27 | def mouseReleaseEvent(self, event): 28 | self.pos2[0], self.pos2[1] = event.pos().x(), event.pos().y() 29 | self.update() 30 | 31 | if __name__=="__main__": 32 | app = QApplication(sys.argv) 33 | w = MyForm() 34 | w.show() 35 | sys.exit(app.exec_()) 36 | -------------------------------------------------------------------------------- /Chapter22/callGoogleMap3.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from googlemaps.client import Client 5 | from googlemaps.distance_matrix import distance_matrix 6 | 7 | from demoGoogleMap3 import * 8 | 9 | class MyForm(QDialog): 10 | def __init__(self): 11 | super().__init__() 12 | self.ui = Ui_Dialog() 13 | self.ui.setupUi(self) 14 | self.ui.pushButtonFindDistance.clicked.connect(self.displayDistance) 15 | self.show() 16 | 17 | def displayDistance(self): 18 | api_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 19 | gmaps = Client(api_key) 20 | data = distance_matrix(gmaps, self.ui.lineEditFirstLocation.text(), self.ui.lineEditSecondLocation.text()) 21 | distance = data['rows'][0]['elements'][0]['distance']['text'] 22 | self.ui.labelDistance.setText("Distance between "+self.ui.lineEditFirstLocation.text()+" and "+self.ui.lineEditSecondLocation.text()+" is "+str(distance)) 23 | 24 | if __name__=="__main__": 25 | app = QApplication(sys.argv) 26 | w = MyForm() 27 | w.show() 28 | sys.exit(app.exec_()) 29 | 30 | 31 | -------------------------------------------------------------------------------- /Chapter13/callCheckBox1.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog 4 | from PyQt5.QtWidgets import QApplication, QWidget, QPushButton 5 | from PyQt5.QtCore import pyqtSlot 6 | from demoCheckBox1 import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.ui.checkBoxCheese.stateChanged.connect(self.dispAmount) 14 | self.ui.checkBoxOlives.stateChanged.connect(self.dispAmount) 15 | self.ui.checkBoxSausages.stateChanged.connect(self.dispAmount) 16 | self.show() 17 | 18 | @pyqtSlot() 19 | def dispAmount(self): 20 | amount=10 21 | if self.ui.checkBoxCheese.isChecked()==True: 22 | amount=amount+1 23 | if self.ui.checkBoxOlives.isChecked()==True: 24 | amount=amount+1 25 | if self.ui.checkBoxSausages.isChecked()==True: 26 | amount=amount+2 27 | self.ui.labelAmount.setText("Total amount for pizza is "+str(amount)) 28 | 29 | if __name__=="__main__": 30 | app = QApplication(sys.argv) 31 | w = MyForm() 32 | w.show() 33 | sys.exit(app.exec_()) 34 | -------------------------------------------------------------------------------- /Chapter16/demoFontDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 30 20 | 60 21 | 331 22 | 221 23 | 24 | 25 | 26 | 27 | 28 | 29 | 120 30 | 10 31 | 111 32 | 31 33 | 34 | 35 | 36 | 37 | 12 38 | 39 | 40 | 41 | Change Font 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Chapter22/callGoogleMap2.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from geolocation.main import GoogleMaps 5 | 6 | from demoGoogleMap2 import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.ui.pushButtonSearch.clicked.connect(self.displayLocation) 14 | self.show() 15 | 16 | def displayLocation(self): 17 | lng = float(self.ui.lineEditLongitude.text()) 18 | lat = float(self.ui.lineEditLatitude.text()) 19 | google_maps = GoogleMaps(api_key='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') 20 | my_location = google_maps.search(lat=lat, lng=lng).first() 21 | self.ui.labelLocation.setText("Location: "+str(my_location)) 22 | self.ui.labelCity.setText("City: "+str(my_location.city)) 23 | self.ui.labelCountry.setText("Country: "+str(my_location.country)) 24 | self.ui.labelPostalCode.setText("Postal Code: "+str(my_location.postal_code)) 25 | 26 | if __name__=="__main__": 27 | app = QApplication(sys.argv) 28 | w = MyForm() 29 | w.show() 30 | sys.exit(app.exec_()) 31 | 32 | 33 | -------------------------------------------------------------------------------- /Chapter22/callGoogleMap1.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from geolocation.main import GoogleMaps 5 | 6 | from demoGoogleMap1 import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.ui.pushButtonSearch.clicked.connect(self.displayDetails) 14 | self.show() 15 | 16 | def displayDetails(self): 17 | address = str(self.ui.lineEditLocation.text()) 18 | google_maps = GoogleMaps(api_key='AIzaSyB3jE8Vd0tiGA8gYh4PamNJa2Dalngjpl0') 19 | location = google_maps.search(location=address) # sends search to Google Maps. 20 | my_location = location.first() 21 | self.ui.labelCity.setText("City: "+str(my_location.city)) 22 | self.ui.labelPostalCode.setText("Postal Code: " +str(my_location.postal_code)) 23 | self.ui.labelLongitude.setText("Longitude: "+str(my_location.lng)) 24 | self.ui.labelLatitude.setText("Latitude: "+str(my_location.lat)) 25 | 26 | if __name__=="__main__": 27 | app = QApplication(sys.argv) 28 | w = MyForm() 29 | w.show() 30 | sys.exit(app.exec_()) 31 | 32 | 33 | -------------------------------------------------------------------------------- /Chapter19/callInsertRows.pyw: -------------------------------------------------------------------------------- 1 | import sqlite3, sys 2 | from PyQt5.QtWidgets import QDialog, QApplication 3 | from sqlite3 import Error 4 | 5 | from demoInsertRowsInTable import * 6 | 7 | class MyForm(QDialog): 8 | 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.ui.pushButtonInsertRow.clicked.connect(self.InsertRows) 14 | self.show() 15 | 16 | def InsertRows(self): 17 | sqlStatement="INSERT INTO "+self.ui.lineEditTableName.text()+" VALUES('"+self.ui.lineEditEmailAddress.text()+"', '"+self.ui.lineEditPassword.text()+"')" 18 | try: 19 | conn = sqlite3.connect(self.ui.lineEditDBName.text()+".db") 20 | with conn: 21 | cur = conn.cursor() 22 | cur.execute(sqlStatement) 23 | conn.commit() 24 | self.ui.labelResponse.setText("Row successfully inserted") 25 | except Error as e: 26 | self.ui.labelResponse.setText("Error in inserting row") 27 | finally: 28 | conn.close() 29 | 30 | if __name__=="__main__": 31 | app = QApplication(sys.argv) 32 | w = MyForm() 33 | w.show() 34 | sys.exit(app.exec_()) 35 | -------------------------------------------------------------------------------- /Chapter20/callDrawRectangle.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from PyQt5.QtGui import QPainter 5 | 6 | from demoDrawRectangle import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.pos1 = [0,0] 14 | self.pos2 = [0,0] 15 | self.show() 16 | 17 | def paintEvent(self, event): 18 | width = self.pos2[0]-self.pos1[0] 19 | height = self.pos2[1] - self.pos1[1] 20 | qp = QPainter() 21 | qp.begin(self) 22 | qp.drawRect(self.pos1[0], self.pos1[1], width, height) 23 | qp.end() 24 | 25 | def mousePressEvent(self, event): 26 | if event.buttons() & QtCore.Qt.LeftButton: 27 | self.pos1[0], self.pos1[1] = event.pos().x(), event.pos().y() 28 | 29 | def mouseReleaseEvent(self, event): 30 | self.pos2[0], self.pos2[1] = event.pos().x(), event.pos().y() 31 | self.update() 32 | 33 | if __name__=="__main__": 34 | app = QApplication(sys.argv) 35 | w = MyForm() 36 | w.show() 37 | sys.exit(app.exec_()) 38 | -------------------------------------------------------------------------------- /Chapter16/demoFontDialog.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoFontDialog.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(400, 300) 15 | self.textEdit = QtWidgets.QTextEdit(Dialog) 16 | self.textEdit.setGeometry(QtCore.QRect(30, 60, 331, 221)) 17 | self.textEdit.setObjectName("textEdit") 18 | self.pushButtonFont = QtWidgets.QPushButton(Dialog) 19 | self.pushButtonFont.setGeometry(QtCore.QRect(120, 10, 111, 31)) 20 | font = QtGui.QFont() 21 | font.setPointSize(12) 22 | self.pushButtonFont.setFont(font) 23 | self.pushButtonFont.setObjectName("pushButtonFont") 24 | 25 | self.retranslateUi(Dialog) 26 | QtCore.QMetaObject.connectSlotsByName(Dialog) 27 | 28 | def retranslateUi(self, Dialog): 29 | _translate = QtCore.QCoreApplication.translate 30 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 31 | self.pushButtonFont.setText(_translate("Dialog", "Change Font")) 32 | 33 | -------------------------------------------------------------------------------- /Chapter10/ABQ_Data_Entry/abq_data_entry/test/support.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from unittest import TestCase 3 | 4 | class TkTestCase(TestCase): 5 | """A test case designed for Tkinter widgets and views""" 6 | 7 | keysyms = { 8 | '-': 'minus', 9 | ' ': 'space', 10 | ':': 'colon', 11 | # For more see http://www.tcl.tk/man/tcl8.4/TkCmd/keysyms.htm 12 | } 13 | @classmethod 14 | def setUpClass(cls): 15 | cls.root = tk.Tk() 16 | cls.root.wait_visibility() 17 | 18 | @classmethod 19 | def tearDownClass(cls): 20 | cls.root.update() 21 | cls.root.destroy() 22 | 23 | def type_in_widget(self, widget, string): 24 | widget.focus_force() 25 | for char in string: 26 | char = self.keysyms.get(char, char) 27 | widget.event_generate(''.format(char)) 28 | widget.event_generate(''.format(char)) 29 | self.root.update() 30 | 31 | def click_on_widget(self, widget, x, y, button=1): 32 | widget.focus_force() 33 | self.root.update() 34 | widget.event_generate("".format(button), x=x, y=y) 35 | widget.event_generate("".format(button), x=x, y=y) 36 | self.root.update() 37 | -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/abq_data_entry/test/support.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from unittest import TestCase 3 | 4 | class TkTestCase(TestCase): 5 | """A test case designed for Tkinter widgets and views""" 6 | 7 | keysyms = { 8 | '-': 'minus', 9 | ' ': 'space', 10 | ':': 'colon', 11 | # For more see http://www.tcl.tk/man/tcl8.4/TkCmd/keysyms.htm 12 | } 13 | @classmethod 14 | def setUpClass(cls): 15 | cls.root = tk.Tk() 16 | cls.root.wait_visibility() 17 | 18 | @classmethod 19 | def tearDownClass(cls): 20 | cls.root.update() 21 | cls.root.destroy() 22 | 23 | def type_in_widget(self, widget, string): 24 | widget.focus_force() 25 | for char in string: 26 | char = self.keysyms.get(char, char) 27 | widget.event_generate(''.format(char)) 28 | widget.event_generate(''.format(char)) 29 | self.root.update() 30 | 31 | def click_on_widget(self, widget, x, y, button=1): 32 | widget.focus_force() 33 | self.root.update() 34 | widget.event_generate("".format(button), x=x, y=y) 35 | widget.event_generate("".format(button), x=x, y=y) 36 | self.root.update() 37 | -------------------------------------------------------------------------------- /Chapter12/ABQ_Data_Entry/abq_data_entry/test/support.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from unittest import TestCase 3 | 4 | class TkTestCase(TestCase): 5 | """A test case designed for Tkinter widgets and views""" 6 | 7 | keysyms = { 8 | '-': 'minus', 9 | ' ': 'space', 10 | ':': 'colon', 11 | # For more see http://www.tcl.tk/man/tcl8.4/TkCmd/keysyms.htm 12 | } 13 | @classmethod 14 | def setUpClass(cls): 15 | cls.root = tk.Tk() 16 | cls.root.wait_visibility() 17 | 18 | @classmethod 19 | def tearDownClass(cls): 20 | cls.root.update() 21 | cls.root.destroy() 22 | 23 | def type_in_widget(self, widget, string): 24 | widget.focus_force() 25 | for char in string: 26 | char = self.keysyms.get(char, char) 27 | widget.event_generate(''.format(char)) 28 | widget.event_generate(''.format(char)) 29 | self.root.update() 30 | 31 | def click_on_widget(self, widget, x, y, button=1): 32 | widget.focus_force() 33 | self.root.update() 34 | widget.event_generate("".format(button), x=x, y=y) 35 | widget.event_generate("".format(button), x=x, y=y) 36 | self.root.update() 37 | -------------------------------------------------------------------------------- /Chapter20/callDrawText.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from PyQt5.QtGui import QPainter, QColor, QFont 5 | from PyQt5.QtCore import Qt 6 | 7 | from demoDrawText import * 8 | 9 | class MyForm(QDialog): 10 | 11 | def __init__(self): 12 | super().__init__() 13 | self.ui = Ui_Dialog() 14 | self.ui.setupUi(self) 15 | self.ui.pushButtonDrawText.clicked.connect(self.dispText) 16 | self.textToDraw="" 17 | self.fontName="Courier New" 18 | self.fontSize=5 19 | self.show() 20 | 21 | def paintEvent(self, event): 22 | qp = QPainter() 23 | qp.begin(self) 24 | qp.setPen(QColor(168, 34, 3)) 25 | qp.setFont(QFont(self.fontName, self.fontSize)) 26 | qp.drawText(event.rect(), Qt.AlignCenter, self.textToDraw) 27 | qp.end() 28 | 29 | def dispText(self): 30 | self.fontName=self.ui.listWidgetFont.currentItem().text() 31 | self.fontSize=int(self.ui.comboBoxFontSize.itemText(self.ui.comboBoxFontSize.currentIndex())) 32 | self.textToDraw=self.ui.textEdit.toPlainText() 33 | self.update() 34 | 35 | if __name__=="__main__": 36 | app = QApplication(sys.argv) 37 | w = MyForm() 38 | w.show() 39 | sys.exit(app.exec_()) 40 | -------------------------------------------------------------------------------- /Chapter07/treeview_demo.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | from pathlib import Path 4 | 5 | # Set up root window 6 | root = tk.Tk() 7 | 8 | # Create list of paths 9 | paths = Path('.').glob('**/*') 10 | 11 | 12 | def sort(tv, col): 13 | itemlist = list(tv.get_children('')) 14 | itemlist.sort(key=lambda x: tv.set(x, col)) 15 | for index, iid in enumerate(itemlist): 16 | tv.move(iid, tv.parent(iid), index) 17 | 18 | # Create and configure treeview 19 | tv = ttk.Treeview(root, columns=['size', 'modified'], selectmode='none') 20 | tv.heading('#0', text='Name', command=lambda: sort(tv, '#0')) 21 | tv.heading('size', text='Size', anchor='center', 22 | command=lambda: sort(tv, 'size')) 23 | tv.heading('modified', text='Modified', anchor='e', 24 | command=lambda: sort(tv, 'modified')) 25 | tv.column('#0', stretch=True) 26 | tv.column('size', width=200) 27 | 28 | tv.pack(expand=True, fill='both') 29 | 30 | # Populate Treeview 31 | for path in paths: 32 | meta = path.stat() 33 | parent = str(path.parent) 34 | if parent == '.': 35 | parent = '' 36 | tv.insert( 37 | parent, 38 | 'end', 39 | iid=str(path), 40 | text=str(path.name), 41 | values=[meta.st_size, meta.st_mtime] 42 | ) 43 | 44 | root.mainloop() 45 | -------------------------------------------------------------------------------- /Chapter14/callScrollBar.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoScrollBar import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.horizontalScrollBarSugarLevel.valueChanged.connect(self.scrollhorizontal) 13 | self.ui.verticalScrollBarPulseRate.valueChanged.connect(self.scrollvertical) 14 | self.ui.horizontalSliderBloodPressure.valueChanged.connect(self.sliderhorizontal) 15 | self.ui.verticalSliderCholestrolLevel.valueChanged.connect(self.slidervertical) 16 | self.show() 17 | 18 | def scrollhorizontal(self,value): 19 | self.ui.lineEditResult.setText("Sugar Level : "+str(value)) 20 | 21 | def scrollvertical(self, value): 22 | self.ui.lineEditResult.setText("Pulse Rate : "+str(value)) 23 | 24 | def sliderhorizontal(self, value): 25 | self.ui.lineEditResult.setText("Blood Pressure : "+str(value)) 26 | 27 | def slidervertical(self, value): 28 | self.ui.lineEditResult.setText("Cholestrol Level : "+str(value)) 29 | 30 | 31 | if __name__=="__main__": 32 | app = QApplication(sys.argv) 33 | w = MyForm() 34 | w.show() 35 | sys.exit(app.exec_()) 36 | -------------------------------------------------------------------------------- /Chapter20/demoDrawDot.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoDrawDot.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(402, 259) 15 | self.label = QtWidgets.QLabel(Dialog) 16 | self.label.setGeometry(QtCore.QRect(20, 10, 361, 51)) 17 | font = QtGui.QFont() 18 | font.setPointSize(12) 19 | self.label.setFont(font) 20 | self.label.setObjectName("label") 21 | 22 | self.retranslateUi(Dialog) 23 | QtCore.QMetaObject.connectSlotsByName(Dialog) 24 | 25 | def retranslateUi(self, Dialog): 26 | _translate = QtCore.QCoreApplication.translate 27 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 28 | self.label.setText(_translate("Dialog", "Click the mouse where you want to display a dot")) 29 | 30 | 31 | if __name__ == "__main__": 32 | import sys 33 | app = QtWidgets.QApplication(sys.argv) 34 | Dialog = QtWidgets.QDialog() 35 | ui = Ui_Dialog() 36 | ui.setupUi(Dialog) 37 | Dialog.show() 38 | sys.exit(app.exec_()) 39 | 40 | -------------------------------------------------------------------------------- /Chapter21/demoAnimation3.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 495 10 | 282 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 180 20 | 100 21 | 121 22 | 31 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | Bounce 32 | 33 | 34 | 35 | 36 | 37 | 0 38 | 0 39 | 81 40 | 91 41 | 42 | 43 | 44 | 45 | 46 | 47 | coloredball.jpg 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Chapter21/demoAnimation1.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 238 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 50 21 | 121 22 | 23 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | Move Down 32 | 33 | 34 | 35 | 36 | 37 | 160 38 | 60 39 | 91 40 | 91 41 | 42 | 43 | 44 | 45 | 46 | 47 | coloredball.jpg 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Chapter21/demoAnimation4.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 495 10 | 282 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 170 20 | 100 21 | 141 22 | 31 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | Move With Curve 32 | 33 | 34 | 35 | 36 | 37 | 10 38 | 0 39 | 81 40 | 91 41 | 42 | 43 | 44 | 45 | 46 | 47 | coloredball.jpg 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Chapter19/callSignInForm.pyw: -------------------------------------------------------------------------------- 1 | import sqlite3, sys 2 | from PyQt5.QtWidgets import QDialog, QApplication 3 | from sqlite3 import Error 4 | 5 | from demoSignInForm import * 6 | 7 | class MyForm(QDialog): 8 | 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.ui.pushButtonSearch.clicked.connect(self.SearchRows) 14 | self.show() 15 | 16 | def SearchRows(self): 17 | sqlStatement="SELECT EmailAddress, Password FROM Users where EmailAddress like '"+self.ui.lineEditEmailAddress.text()+"' and Password like '"+ self.ui.lineEditPassword.text()+"'" 18 | try: 19 | conn = sqlite3.connect("ECommerce.db") 20 | cur = conn.cursor() 21 | cur.execute(sqlStatement) 22 | row = cur.fetchone() 23 | if row==None: 24 | self.ui.labelResponse.setText("Sorry, Incorrect email address or password ") 25 | else: 26 | self.ui.labelResponse.setText("You are welcome ") 27 | except Error as e: 28 | self.ui.labelResponse.setText("Error in accessing row") 29 | finally: 30 | conn.close() 31 | 32 | if __name__=="__main__": 33 | app = QApplication(sys.argv) 34 | w = MyForm() 35 | w.show() 36 | sys.exit(app.exec_()) 37 | -------------------------------------------------------------------------------- /Chapter20/demoDrawLine.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoDrawLine.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(500, 340) 15 | self.label = QtWidgets.QLabel(Dialog) 16 | self.label.setGeometry(QtCore.QRect(20, 10, 461, 51)) 17 | font = QtGui.QFont() 18 | font.setPointSize(12) 19 | self.label.setFont(font) 20 | self.label.setObjectName("label") 21 | 22 | self.retranslateUi(Dialog) 23 | QtCore.QMetaObject.connectSlotsByName(Dialog) 24 | 25 | def retranslateUi(self, Dialog): 26 | _translate = QtCore.QCoreApplication.translate 27 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 28 | self.label.setText(_translate("Dialog", "Click the mouse and drag it to draw the line of desired size")) 29 | 30 | 31 | if __name__ == "__main__": 32 | import sys 33 | app = QtWidgets.QApplication(sys.argv) 34 | Dialog = QtWidgets.QDialog() 35 | ui = Ui_Dialog() 36 | ui.setupUi(Dialog) 37 | Dialog.show() 38 | sys.exit(app.exec_()) 39 | 40 | -------------------------------------------------------------------------------- /Chapter20/callDrawCircle.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from PyQt5.QtGui import QPainter 5 | 6 | from demoDrawCircle import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.pos1 = [0,0] 14 | self.pos2 = [0,0] 15 | self.show() 16 | 17 | def paintEvent(self, event): 18 | width = self.pos2[0]-self.pos1[0] 19 | height = self.pos2[1] - self.pos1[1] 20 | qp = QPainter() 21 | qp.begin(self) 22 | rect = QtCore.QRect(self.pos1[0], self.pos1[1], width, height) 23 | startAngle = 0 24 | arcLength = 360 *16 25 | qp.drawArc(rect, startAngle, arcLength) 26 | qp.end() 27 | 28 | def mousePressEvent(self, event): 29 | if event.buttons() & QtCore.Qt.LeftButton: 30 | self.pos1[0], self.pos1[1] = event.pos().x(), event.pos().y() 31 | 32 | def mouseReleaseEvent(self, event): 33 | self.pos2[0], self.pos2[1] = event.pos().x(), event.pos().y() 34 | self.update() 35 | 36 | if __name__=="__main__": 37 | app = QApplication(sys.argv) 38 | w = MyForm() 39 | w.show() 40 | sys.exit(app.exec_()) 41 | -------------------------------------------------------------------------------- /Chapter20/demoDrawCircle.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoDrawCircle.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(500, 340) 15 | self.label = QtWidgets.QLabel(Dialog) 16 | self.label.setGeometry(QtCore.QRect(20, 10, 461, 51)) 17 | font = QtGui.QFont() 18 | font.setPointSize(12) 19 | self.label.setFont(font) 20 | self.label.setObjectName("label") 21 | 22 | self.retranslateUi(Dialog) 23 | QtCore.QMetaObject.connectSlotsByName(Dialog) 24 | 25 | def retranslateUi(self, Dialog): 26 | _translate = QtCore.QCoreApplication.translate 27 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 28 | self.label.setText(_translate("Dialog", "Click the mouse and drag it to draw the circle of desired size")) 29 | 30 | 31 | if __name__ == "__main__": 32 | import sys 33 | app = QtWidgets.QApplication(sys.argv) 34 | Dialog = QtWidgets.QDialog() 35 | ui = Ui_Dialog() 36 | ui.setupUi(Dialog) 37 | Dialog.show() 38 | sys.exit(app.exec_()) 39 | 40 | -------------------------------------------------------------------------------- /Chapter16/callFileDialog.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QMainWindow, QApplication, QAction, QFileDialog 4 | 5 | from demoFileDialog import * 6 | 7 | class MyForm(QMainWindow): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_MainWindow() 11 | self.ui.setupUi(self) 12 | self.ui.actionOpen.triggered.connect(self.openFileDialog) 13 | self.ui.actionSave.triggered.connect(self.saveFileDialog) 14 | self.show() 15 | 16 | def openFileDialog(self): 17 | 18 | fname = QFileDialog.getOpenFileName(self, 'Open file', '/home') 19 | 20 | if fname[0]: 21 | f = open(fname[0], 'r') 22 | 23 | with f: 24 | data = f.read() 25 | self.ui.textEdit.setText(data) 26 | 27 | def saveFileDialog(self): 28 | options = QFileDialog.Options() 29 | options |= QFileDialog.DontUseNativeDialog 30 | fileName, _ = QFileDialog.getSaveFileName(self,"QFileDialog.getSaveFileName()","","All Files (*);;Text Files (*.txt)", options=options) 31 | f = open(fileName,'w') 32 | text = self.ui.textEdit.toPlainText() 33 | f.write(text) 34 | f.close() 35 | 36 | if __name__=="__main__": 37 | app = QApplication(sys.argv) 38 | w = MyForm() 39 | w.show() 40 | sys.exit(app.exec_()) 41 | 42 | -------------------------------------------------------------------------------- /Chapter20/demoDrawRectangle.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoDrawRectangle.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(500, 340) 15 | self.label = QtWidgets.QLabel(Dialog) 16 | self.label.setGeometry(QtCore.QRect(20, 10, 461, 51)) 17 | font = QtGui.QFont() 18 | font.setPointSize(12) 19 | self.label.setFont(font) 20 | self.label.setObjectName("label") 21 | 22 | self.retranslateUi(Dialog) 23 | QtCore.QMetaObject.connectSlotsByName(Dialog) 24 | 25 | def retranslateUi(self, Dialog): 26 | _translate = QtCore.QCoreApplication.translate 27 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 28 | self.label.setText(_translate("Dialog", "Click the mouse and drag it to draw the rectangle of desired size")) 29 | 30 | 31 | if __name__ == "__main__": 32 | import sys 33 | app = QtWidgets.QApplication(sys.argv) 34 | Dialog = QtWidgets.QDialog() 35 | ui = Ui_Dialog() 36 | ui.setupUi(Dialog) 37 | Dialog.show() 38 | sys.exit(app.exec_()) 39 | 40 | -------------------------------------------------------------------------------- /Chapter20/demoMousetrack.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 495 10 | 267 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 60 21 | 461 22 | 20 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 20 38 | 10 39 | 471 40 | 31 41 | 42 | 43 | 44 | 45 | 12 46 | 47 | 48 | 49 | This app will display x,y co-ordinates where mouse is moved on 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Chapter21/demoAnimation4.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoAnimation4.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(495, 282) 15 | self.pushButtonMoveCurve = QtWidgets.QPushButton(Dialog) 16 | self.pushButtonMoveCurve.setGeometry(QtCore.QRect(170, 100, 141, 31)) 17 | font = QtGui.QFont() 18 | font.setPointSize(12) 19 | self.pushButtonMoveCurve.setFont(font) 20 | self.pushButtonMoveCurve.setObjectName("pushButtonMoveCurve") 21 | self.labelPic = QtWidgets.QLabel(Dialog) 22 | self.labelPic.setGeometry(QtCore.QRect(10, 0, 81, 91)) 23 | self.labelPic.setText("") 24 | self.labelPic.setPixmap(QtGui.QPixmap("coloredball.jpg")) 25 | self.labelPic.setObjectName("labelPic") 26 | 27 | self.retranslateUi(Dialog) 28 | QtCore.QMetaObject.connectSlotsByName(Dialog) 29 | 30 | def retranslateUi(self, Dialog): 31 | _translate = QtCore.QCoreApplication.translate 32 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 33 | self.pushButtonMoveCurve.setText(_translate("Dialog", "Move With Curve")) 34 | 35 | -------------------------------------------------------------------------------- /Chapter19/callSearchRows.pyw: -------------------------------------------------------------------------------- 1 | import sqlite3, sys 2 | from PyQt5.QtWidgets import QDialog, QApplication 3 | from sqlite3 import Error 4 | 5 | from demoSearchRows import * 6 | 7 | class MyForm(QDialog): 8 | 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.ui.pushButtonSearch.clicked.connect(self.SearchRows) 14 | self.show() 15 | 16 | def SearchRows(self): 17 | sqlStatement="SELECT Password FROM "+self.ui.lineEditTableName.text()+" where EmailAddress like '"+self.ui.lineEditEmailAddress.text()+"'" 18 | try: 19 | conn = sqlite3.connect(self.ui.lineEditDBName.text()+".db") 20 | cur = conn.cursor() 21 | cur.execute(sqlStatement) 22 | row = cur.fetchone() 23 | if row==None: 24 | self.ui.labelResponse.setText("Sorry, No User found with this email address") 25 | self.ui.lineEditPassword.setText("") 26 | else: 27 | self.ui.labelResponse.setText("Email Address Found, Password of this User is :") 28 | self.ui.lineEditPassword.setText(row[0]) 29 | except Error as e: 30 | self.ui.labelResponse.setText("Error in accessing row") 31 | finally: 32 | conn.close() 33 | 34 | if __name__=="__main__": 35 | app = QApplication(sys.argv) 36 | w = MyForm() 37 | w.show() 38 | sys.exit(app.exec_()) 39 | -------------------------------------------------------------------------------- /Chapter21/callAnimation4.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from PyQt5.QtCore import QRect, QPointF, QPropertyAnimation, pyqtProperty 5 | from PyQt5.QtGui import QPainter, QPainterPath 6 | 7 | from demoAnimation4 import * 8 | 9 | class MyForm(QDialog): 10 | def __init__(self): 11 | super().__init__() 12 | self.ui = Ui_Dialog() 13 | self.ui.setupUi(self) 14 | self.ui.pushButtonMoveCurve.clicked.connect(self.startAnimation) 15 | self.path = QPainterPath() 16 | self.path.moveTo(30, 30) 17 | self.path.cubicTo(30, 30, 80, 180, 180, 170) 18 | self.ui.labelPic.pos = QPointF(20, 20) 19 | self.show() 20 | 21 | def paintEvent(self, e): 22 | qp = QPainter() 23 | qp.begin(self) 24 | qp.drawPath(self.path) 25 | qp.end() 26 | 27 | def startAnimation(self): 28 | self.anim = QPropertyAnimation(self.ui.labelPic, b'pos') 29 | self.anim.setDuration(4000) 30 | self.anim.setStartValue(QPointF(20, 20)) 31 | positionValues = [n/80 for n in range(0, 50)] 32 | for i in positionValues: 33 | self.anim.setKeyValueAt(i, self.path.pointAtPercent(i)) 34 | self.anim.setEndValue(QPointF(160, 150)) 35 | self.anim.start() 36 | 37 | if __name__=="__main__": 38 | app = QApplication(sys.argv) 39 | w = MyForm() 40 | w.show() 41 | sys.exit(app.exec_()) 42 | -------------------------------------------------------------------------------- /Chapter14/calldemoSpinner.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoSpinBox import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.spinBoxBookQty.editingFinished.connect(self.result1) 13 | self.ui.doubleSpinBoxSugarWeight.editingFinished.connect(self.result2) 14 | self.show() 15 | 16 | def result1(self): 17 | if len(self.ui.lineEditBookPrice.text())!=0: 18 | bookPrice=int(self.ui.lineEditBookPrice.text()) 19 | else: 20 | bookPrice=0 21 | totalBookAmount=self.ui.spinBoxBookQty.value() * bookPrice 22 | self.ui.lineEditBookAmount.setText(str(totalBookAmount)) 23 | 24 | def result2(self): 25 | if len(self.ui.lineEditSugarPrice.text())!=0: 26 | sugarPrice=float(self.ui.lineEditSugarPrice.text()) 27 | else: 28 | sugarPrice=0 29 | totalSugarAmount=self.ui.doubleSpinBoxSugarWeight.value() * sugarPrice 30 | self.ui.lineEditSugarAmount.setText(str(round(totalSugarAmount,2))) 31 | totalBookAmount=int(self.ui.lineEditBookAmount.text()) 32 | totalAmount=totalBookAmount+totalSugarAmount 33 | self.ui.labelTotalAmount.setText(str(round(totalAmount,2))) 34 | 35 | if __name__=="__main__": 36 | app = QApplication(sys.argv) 37 | w = MyForm() 38 | w.show() 39 | sys.exit(app.exec_()) 40 | -------------------------------------------------------------------------------- /Chapter08/ttk_combobox_info.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | from pprint import pprint 4 | 5 | root = tk.Tk() 6 | style = ttk.Style() 7 | 8 | print('TTK Combobox\n') 9 | 10 | cb = ttk.Combobox(root) 11 | cb_stylename = cb.winfo_class() 12 | print("Style name: ", cb_stylename) 13 | print("Starting state:", cb.state()) 14 | cb.state(['active', 'invalid']) 15 | print("New state:", cb.state()) 16 | cb.state(['!invalid']) 17 | print("Newer state: ", cb.state()) 18 | 19 | cb_layout = style.layout(cb_stylename) 20 | print("\nLayout: ") 21 | pprint(cb_layout) 22 | 23 | def walk_layout(layout): 24 | for element, subelements in layout: 25 | print("\nOptions for {}:".format(element)) 26 | pprint(style.element_options(element)) 27 | if subelements.get("children"): 28 | walk_layout(subelements.get("children")) 29 | walk_layout(cb_layout) 30 | 31 | cb_map = style.map(cb_stylename) 32 | print("\nDefault Map:") 33 | pprint(cb_map) 34 | 35 | style.map(cb_stylename, 36 | fieldbackground=[ 37 | ('!invalid', 'blue'), 38 | ('invalid', 'red') 39 | ], 40 | font=[ 41 | ('!invalid', 'Helvetica 20 normal'), 42 | ('invalid', 'Helvetica 20 bold') 43 | ]) 44 | 45 | cb_map = style.map(cb_stylename) 46 | print("\nNew Map:") 47 | pprint(cb_map) 48 | 49 | print('\nAvailable Themes:') 50 | pprint(style.theme_names()) 51 | 52 | print('\nCurrent Theme:', style.theme_use()) 53 | 54 | pprint(style.element_names()) 55 | -------------------------------------------------------------------------------- /Chapter19/callDisplayRows.pyw: -------------------------------------------------------------------------------- 1 | import sqlite3, sys 2 | from PyQt5.QtWidgets import QDialog, QApplication,QTableWidgetItem 3 | from sqlite3 import Error 4 | 5 | from demoDisplayRowsOfTable import * 6 | 7 | 8 | class MyForm(QDialog): 9 | 10 | def __init__(self): 11 | super().__init__() 12 | self.ui = Ui_Dialog() 13 | self.ui.setupUi(self) 14 | self.ui.pushButtonDisplayRows.clicked.connect(self.DisplayRows) 15 | self.show() 16 | 17 | def DisplayRows(self): 18 | sqlStatement="SELECT * FROM "+self.ui.lineEditTableName.text() 19 | try: 20 | conn = sqlite3.connect(self.ui.lineEditDBName.text()+".db") 21 | cur = conn.cursor() 22 | cur.execute(sqlStatement) 23 | rows = cur.fetchall() 24 | rowNo=0 25 | for tuple in rows: 26 | self.ui.labelResponse.setText("") 27 | colNo=0 28 | for columns in tuple: 29 | oneColumn=QTableWidgetItem(columns) 30 | self.ui.tableWidget.setItem(rowNo, colNo, oneColumn) 31 | colNo+=1 32 | rowNo+=1 33 | 34 | except Error as e: 35 | self.ui.tableWidget.clear() 36 | self.ui.labelResponse.setText("Error in accessing table") 37 | finally: 38 | conn.close() 39 | 40 | if __name__=="__main__": 41 | app = QApplication(sys.argv) 42 | w = MyForm() 43 | w.show() 44 | sys.exit(app.exec_()) 45 | -------------------------------------------------------------------------------- /Chapter06/menu_demo.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | 3 | root = tk.Tk() 4 | main_text = tk.StringVar(value='Hi') 5 | label = tk.Label(root, textvariable=main_text) 6 | label.pack() 7 | 8 | main_menu = tk.Menu(root) 9 | root.config(menu=main_menu) 10 | 11 | main_menu.add('command', label='Quit', command=root.quit) 12 | 13 | text_menu = tk.Menu(main_menu, tearoff=False) 14 | text_menu.add_command(label='Set to "Hi"', 15 | command=lambda: main_text.set('Hi')) 16 | text_menu.add_command(label='Set to "There"', 17 | command=lambda: main_text.set('There')) 18 | main_menu.add_cascade(label="Text", menu=text_menu) 19 | 20 | font_bold = tk.BooleanVar() 21 | font_size = tk.IntVar() 22 | 23 | def set_font(*args): 24 | font_spec = 'TkDefaultFont {size} {bold}'.format( 25 | size=font_size.get(), 26 | bold='bold' if font_bold.get() else '') 27 | label.config(font=font_spec) 28 | 29 | 30 | font_bold.trace('w', set_font) 31 | font_size.trace('w', set_font) 32 | 33 | # appearance menu 34 | appearance_menu = tk.Menu(main_menu, tearoff=False) 35 | main_menu.add_cascade(label="Appearance", menu=appearance_menu) 36 | 37 | # bold text button 38 | appearance_menu.add_checkbutton(label="Bold", variable=font_bold) 39 | 40 | # size menu 41 | size_menu = tk.Menu(appearance_menu, tearoff=False) 42 | appearance_menu.add_cascade(label='Font size', menu=size_menu) 43 | for size in range(8, 24, 2): 44 | size_menu.add_radiobutton( 45 | label="{} px".format(size), 46 | value=size, variable=font_size) 47 | 48 | root.mainloop() 49 | -------------------------------------------------------------------------------- /Chapter21/demoAnimation3.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoAnimation3.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(495, 282) 15 | self.pushButtonBounce = QtWidgets.QPushButton(Dialog) 16 | self.pushButtonBounce.setGeometry(QtCore.QRect(180, 100, 121, 31)) 17 | font = QtGui.QFont() 18 | font.setPointSize(12) 19 | self.pushButtonBounce.setFont(font) 20 | self.pushButtonBounce.setObjectName("pushButtonBounce") 21 | self.labelPic = QtWidgets.QLabel(Dialog) 22 | self.labelPic.setGeometry(QtCore.QRect(0, 0, 81, 91)) 23 | self.labelPic.setText("") 24 | self.labelPic.setPixmap(QtGui.QPixmap("coloredball.jpg")) 25 | self.labelPic.setObjectName("labelPic") 26 | 27 | self.retranslateUi(Dialog) 28 | QtCore.QMetaObject.connectSlotsByName(Dialog) 29 | 30 | def retranslateUi(self, Dialog): 31 | _translate = QtCore.QCoreApplication.translate 32 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 33 | self.pushButtonBounce.setText(_translate("Dialog", "Bounce")) 34 | 35 | 36 | if __name__ == "__main__": 37 | import sys 38 | app = QtWidgets.QApplication(sys.argv) 39 | Dialog = QtWidgets.QDialog() 40 | ui = Ui_Dialog() 41 | ui.setupUi(Dialog) 42 | Dialog.show() 43 | sys.exit(app.exec_()) 44 | 45 | -------------------------------------------------------------------------------- /Chapter21/demoAnimation1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoAnimation1.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(400, 238) 15 | self.pushButtonMoveDown = QtWidgets.QPushButton(Dialog) 16 | self.pushButtonMoveDown.setGeometry(QtCore.QRect(20, 50, 121, 23)) 17 | font = QtGui.QFont() 18 | font.setPointSize(12) 19 | self.pushButtonMoveDown.setFont(font) 20 | self.pushButtonMoveDown.setObjectName("pushButtonMoveDown") 21 | self.labelPic = QtWidgets.QLabel(Dialog) 22 | self.labelPic.setGeometry(QtCore.QRect(160, 60, 91, 91)) 23 | self.labelPic.setText("") 24 | self.labelPic.setPixmap(QtGui.QPixmap("coloredball.jpg")) 25 | self.labelPic.setObjectName("labelPic") 26 | 27 | self.retranslateUi(Dialog) 28 | QtCore.QMetaObject.connectSlotsByName(Dialog) 29 | 30 | def retranslateUi(self, Dialog): 31 | _translate = QtCore.QCoreApplication.translate 32 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 33 | self.pushButtonMoveDown.setText(_translate("Dialog", "Move Down")) 34 | 35 | 36 | if __name__ == "__main__": 37 | import sys 38 | app = QtWidgets.QApplication(sys.argv) 39 | Dialog = QtWidgets.QDialog() 40 | ui = Ui_Dialog() 41 | ui.setupUi(Dialog) 42 | Dialog.show() 43 | sys.exit(app.exec_()) 44 | 45 | -------------------------------------------------------------------------------- /Chapter20/demoMousetrack.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoMousetrack.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(495, 267) 15 | self.label = QtWidgets.QLabel(Dialog) 16 | self.label.setGeometry(QtCore.QRect(20, 60, 461, 20)) 17 | font = QtGui.QFont() 18 | font.setPointSize(12) 19 | self.label.setFont(font) 20 | self.label.setText("") 21 | self.label.setObjectName("label") 22 | self.label_2 = QtWidgets.QLabel(Dialog) 23 | self.label_2.setGeometry(QtCore.QRect(20, 10, 471, 31)) 24 | font = QtGui.QFont() 25 | font.setPointSize(12) 26 | self.label_2.setFont(font) 27 | self.label_2.setObjectName("label_2") 28 | 29 | self.retranslateUi(Dialog) 30 | QtCore.QMetaObject.connectSlotsByName(Dialog) 31 | 32 | def retranslateUi(self, Dialog): 33 | _translate = QtCore.QCoreApplication.translate 34 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 35 | self.label_2.setText(_translate("Dialog", "This app will display x,y co-ordinates where mouse is moved on")) 36 | 37 | 38 | if __name__ == "__main__": 39 | import sys 40 | app = QtWidgets.QApplication(sys.argv) 41 | Dialog = QtWidgets.QDialog() 42 | ui = Ui_Dialog() 43 | ui.setupUi(Dialog) 44 | Dialog.show() 45 | sys.exit(app.exec_()) 46 | 47 | -------------------------------------------------------------------------------- /Chapter15/callSimpleInheritance.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoSimpleInheritance import * 6 | 7 | class Student: 8 | name = "" 9 | code = "" 10 | 11 | def __init__(self, code, name): 12 | self.code = code 13 | self.name = name 14 | 15 | def getCode(self): 16 | return self.code 17 | 18 | def getName(self): 19 | return self.name 20 | 21 | 22 | class Marks(Student): 23 | historyMarks = 0 24 | geographyMarks = 0 25 | 26 | def __init__(self, code, name, historyMarks, geographyMarks): 27 | Student.__init__(self,code,name) 28 | self.historyMarks = historyMarks 29 | self.geographyMarks = geographyMarks 30 | 31 | def getHistoryMarks(self): 32 | return self.historyMarks 33 | 34 | def getGeographyMarks(self): 35 | return self.geographyMarks 36 | 37 | 38 | class MyForm(QDialog): 39 | def __init__(self): 40 | super().__init__() 41 | self.ui = Ui_Dialog() 42 | self.ui.setupUi(self) 43 | self.ui.ButtonClickMe.clicked.connect(self.dispmessage) 44 | self.show() 45 | 46 | def dispmessage(self): 47 | marksObj=Marks(self.ui.lineEditCode.text(), self.ui.lineEditName.text(), self.ui.lineEditHistoryMarks.text(), self.ui.lineEditGeographyMarks.text()) 48 | self.ui.labelResponse.setText("Code: "+marksObj.getCode()+", Name:"+marksObj.getName()+"\nHistory Marks:"+marksObj.getHistoryMarks()+", Geography Marks:"+marksObj.getGeographyMarks()) 49 | 50 | if __name__=="__main__": 51 | app = QApplication(sys.argv) 52 | w = MyForm() 53 | w.show() 54 | sys.exit(app.exec_()) 55 | -------------------------------------------------------------------------------- /Chapter14/callListWidgetOp.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication, QInputDialog, QListWidgetItem 4 | 5 | from demoListWidgetOp import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.listWidget.addItem('Ice Cream') 13 | self.ui.listWidget.addItem('Soda') 14 | self.ui.listWidget.addItem('Coffee') 15 | self.ui.listWidget.addItem('Chocolate') 16 | self.ui.pushButtonAdd.clicked.connect(self.addlist) 17 | self.ui.pushButtonEdit.clicked.connect(self.editlist) 18 | self.ui.pushButtonDelete.clicked.connect(self.delitem) 19 | self.ui.pushButtonDeleteAll.clicked.connect(self.delallitems) 20 | self.show() 21 | 22 | def addlist(self): 23 | self.ui.listWidget.addItem(self.ui.lineEdit.text()) 24 | self.ui.lineEdit.setText('') 25 | self.ui.lineEdit.setFocus() 26 | 27 | def editlist(self): 28 | row=self.ui.listWidget.currentRow() 29 | newtext, ok=QInputDialog.getText(self, "Enter new text", "Enter new text") 30 | if ok and (len(newtext) !=0): 31 | self.ui.listWidget.takeItem(self.ui.listWidget.currentRow()) 32 | self.ui.listWidget.insertItem(row,QListWidgetItem(newtext)) 33 | 34 | def delitem(self): 35 | self.ui.listWidget.takeItem(self.ui.listWidget.currentRow()) 36 | 37 | def delallitems(self): 38 | self.ui.listWidget.clear() 39 | 40 | 41 | if __name__=="__main__": 42 | app = QApplication(sys.argv) 43 | w = MyForm() 44 | w.show() 45 | sys.exit(app.exec_()) 46 | -------------------------------------------------------------------------------- /Chapter09/unittest_demo/test_mycalc.py: -------------------------------------------------------------------------------- 1 | import mycalc 2 | import unittest 3 | from unittest.mock import Mock, patch 4 | 5 | class TestMyCalc(unittest.TestCase): 6 | 7 | def setUp(self): 8 | self.mycalc1_0 = mycalc.MyCalc(1, 0) 9 | self.mycalc36_12 = mycalc.MyCalc(36, 12) 10 | 11 | def test_add(self): 12 | self.assertEqual(self.mycalc1_0.add(), 1) 13 | self.assertEqual(self.mycalc36_12.add(), 48) 14 | 15 | def test_mod_divide(self): 16 | self.assertEqual(self.mycalc36_12.mod_divide(), (3, 0)) 17 | self.assertRaises(ValueError, self.mycalc1_0.mod_divide) 18 | 19 | with self.assertRaises(ValueError): 20 | self.mycalc1_0.mod_divide() 21 | 22 | def test_rand_between(self): 23 | 24 | # not a good way to do it: 25 | rv = self.mycalc1_0.rand_between() 26 | self.assertLessEqual(rv, 1) 27 | self.assertGreaterEqual(rv, 0) 28 | 29 | # better, but clumsy 30 | fakerandom = Mock(return_value=.5) 31 | orig_random = mycalc.random.random 32 | mycalc.random.random = fakerandom 33 | rv = self.mycalc1_0.rand_between() 34 | self.assertEqual(rv, 0.5) 35 | mycalc.random.random = orig_random 36 | 37 | # clean and neat 38 | with patch('mycalc.random.random') as fakerandom: 39 | fakerandom.return_value = 0.5 40 | rv = self.mycalc1_0.rand_between() 41 | self.assertEqual(rv, 0.5) 42 | 43 | @patch('mycalc.random.random') 44 | def test_rand_between2(self, fakerandom): 45 | fakerandom.return_value = 0.5 46 | rv = self.mycalc1_0.rand_between() 47 | self.assertEqual(rv, 0.5) 48 | 49 | 50 | if __name__ == '__main__': 51 | unittest.main() 52 | -------------------------------------------------------------------------------- /Chapter16/demoInputDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 565 10 | 74 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 20 21 | 131 22 | 20 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | Your Country: 32 | 33 | 34 | 35 | 36 | 37 | 140 38 | 20 39 | 221 40 | 20 41 | 42 | 43 | 44 | 45 | 12 46 | 47 | 48 | 49 | 50 | 51 | 52 | 400 53 | 20 54 | 131 55 | 23 56 | 57 | 58 | 59 | 60 | 12 61 | 62 | 63 | 64 | Choose Country 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Chapter16/demoFileDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 544 10 | 386 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 0 21 | 10 22 | 521 23 | 331 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 0 32 | 0 33 | 544 34 | 21 35 | 36 | 37 | 38 | 39 | File 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Open 50 | 51 | 52 | Ctrl+O 53 | 54 | 55 | 56 | 57 | Save 58 | 59 | 60 | Ctrl+S 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /Chapter16/demoInputDialog.py: -------------------------------------------------------------------------------- 1 | 2 | from PyQt5 import QtCore, QtGui, QtWidgets 3 | 4 | class Ui_Dialog(object): 5 | def setupUi(self, Dialog): 6 | Dialog.setObjectName("Dialog") 7 | Dialog.resize(565, 74) 8 | self.label = QtWidgets.QLabel(Dialog) 9 | self.label.setGeometry(QtCore.QRect(20, 20, 131, 20)) 10 | font = QtGui.QFont() 11 | font.setPointSize(12) 12 | self.label.setFont(font) 13 | self.label.setObjectName("label") 14 | self.lineEditCountry = QtWidgets.QLineEdit(Dialog) 15 | self.lineEditCountry.setGeometry(QtCore.QRect(140, 20, 221, 20)) 16 | font = QtGui.QFont() 17 | font.setPointSize(12) 18 | self.lineEditCountry.setFont(font) 19 | self.lineEditCountry.setObjectName("lineEditCountry") 20 | self.pushButtonCountry = QtWidgets.QPushButton(Dialog) 21 | self.pushButtonCountry.setGeometry(QtCore.QRect(400, 20, 131, 23)) 22 | font = QtGui.QFont() 23 | font.setPointSize(12) 24 | self.pushButtonCountry.setFont(font) 25 | self.pushButtonCountry.setObjectName("pushButtonCountry") 26 | 27 | self.retranslateUi(Dialog) 28 | QtCore.QMetaObject.connectSlotsByName(Dialog) 29 | 30 | def retranslateUi(self, Dialog): 31 | _translate = QtCore.QCoreApplication.translate 32 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 33 | self.label.setText(_translate("Dialog", "Your Country:")) 34 | self.pushButtonCountry.setText(_translate("Dialog", "Choose Country")) 35 | 36 | 37 | if __name__ == "__main__": 38 | import sys 39 | app = QtWidgets.QApplication(sys.argv) 40 | Dialog = QtWidgets.QDialog() 41 | ui = Ui_Dialog() 42 | ui.setupUi(Dialog) 43 | Dialog.show() 44 | sys.exit(app.exec_()) 45 | 46 | -------------------------------------------------------------------------------- /Chapter14/demoProgressBar.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 350 10 | 153 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 40 20 | 60 21 | 281 22 | 23 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | 0 32 | 33 | 34 | 35 | 36 | 37 | 80 38 | 20 39 | 181 40 | 21 41 | 42 | 43 | 44 | 45 | 12 46 | 47 | 48 | 49 | Downloading the file 50 | 51 | 52 | 53 | 54 | 55 | 80 56 | 110 57 | 151 58 | 31 59 | 60 | 61 | 62 | 63 | 12 64 | 65 | 66 | 67 | Start Downloading 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Chapter20/demoMouseClicks.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 565 10 | 265 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 60 21 | 521 22 | 20 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 20 38 | 100 39 | 521 40 | 20 41 | 42 | 43 | 44 | 45 | 12 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 20 56 | 10 57 | 531 58 | 51 59 | 60 | 61 | 62 | 63 | 12 64 | 65 | 66 | 67 | Displays the x, y co-ordinates where mouse button is pressed and released 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Chapter19/callCreateTable.pyw: -------------------------------------------------------------------------------- 1 | import sqlite3, sys 2 | from PyQt5.QtWidgets import QDialog, QApplication 3 | from sqlite3 import Error 4 | 5 | from demoCreateTable import * 6 | 7 | tabledefinition="" 8 | class MyForm(QDialog): 9 | 10 | def __init__(self): 11 | super().__init__() 12 | self.ui = Ui_Dialog() 13 | self.ui.setupUi(self) 14 | self.ui.pushButtonCreateTable.clicked.connect(self.createTable) 15 | self.ui.pushButtonAddColumn.clicked.connect(self.addColumns) 16 | self.show() 17 | 18 | def addColumns(self): 19 | global tabledefinition 20 | if tabledefinition=="": 21 | tabledefinition="CREATE TABLE IF NOT EXISTS "+ self.ui.lineEditTableName.text()+"("+self.ui.lineEditColumnName.text()+" "+self.ui.comboBoxDataType.itemText(self.ui.comboBoxDataType.currentIndex()) 22 | else: 23 | tabledefinition+=", "+self.ui.lineEditColumnName.text()+" "+self.ui.comboBoxDataType.itemText(self.ui.comboBoxDataType.currentIndex()) 24 | self.ui.lineEditColumnName.setText("") 25 | self.ui.lineEditColumnName.setFocus() 26 | 27 | def createTable(self): 28 | global tabledefinition 29 | try: 30 | conn = sqlite3.connect(self.ui.lineEditDBName.text()+".db") 31 | self.ui.labelResponse.setText("Database is connected") 32 | c = conn.cursor() 33 | tabledefinition+=");" 34 | c.execute(tabledefinition) 35 | self.ui.labelResponse.setText("Table is successfully created") 36 | except Error as e: 37 | self.ui.labelResponse.setText("Error in creating table") 38 | finally: 39 | conn.close() 40 | 41 | if __name__=="__main__": 42 | app = QApplication(sys.argv) 43 | w = MyForm() 44 | w.show() 45 | sys.exit(app.exec_()) 46 | -------------------------------------------------------------------------------- /Chapter13/callCheckBox2.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog 4 | from PyQt5.QtWidgets import QApplication, QWidget, QPushButton 5 | from PyQt5.QtCore import pyqtSlot 6 | from demoCheckBox2 import * 7 | 8 | class MyForm(QDialog): 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.ui.checkBoxChoclateAlmond.stateChanged.connect(self.dispAmount) 14 | self.ui.checkBoxChoclateChips.stateChanged.connect(self.dispAmount) 15 | self.ui.checkBoxCookieDough.stateChanged.connect(self.dispAmount) 16 | self.ui.checkBoxRockyRoad.stateChanged.connect(self.dispAmount) 17 | self.ui.checkBoxCoffee.stateChanged.connect(self.dispAmount) 18 | self.ui.checkBoxSoda.stateChanged.connect(self.dispAmount) 19 | self.ui.checkBoxTea.stateChanged.connect(self.dispAmount) 20 | 21 | self.show() 22 | 23 | @pyqtSlot() 24 | def dispAmount(self): 25 | amount=0 26 | if self.ui.checkBoxChoclateAlmond.isChecked()==True: 27 | amount=amount+3 28 | if self.ui.checkBoxChoclateChips.isChecked()==True: 29 | amount=amount+4 30 | if self.ui.checkBoxCookieDough.isChecked()==True: 31 | amount=amount+2 32 | if self.ui.checkBoxRockyRoad.isChecked()==True: 33 | amount=amount+5 34 | if self.ui.checkBoxCoffee.isChecked()==True: 35 | amount=amount+2 36 | if self.ui.checkBoxSoda.isChecked()==True: 37 | amount=amount+3 38 | if self.ui.checkBoxTea.isChecked()==True: 39 | amount=amount+1 40 | self.ui.labelAmount.setText("Total amount is $"+str(amount)) 41 | 42 | if __name__=="__main__": 43 | app = QApplication(sys.argv) 44 | w = MyForm() 45 | w.show() 46 | sys.exit(app.exec_()) 47 | -------------------------------------------------------------------------------- /Chapter11/ABQ_Data_Entry/abq_data_entry/network.py: -------------------------------------------------------------------------------- 1 | from urllib.request import urlopen 2 | from xml.etree import ElementTree 3 | import requests 4 | import ftplib as ftp 5 | from os import path 6 | 7 | def get_local_weather(station): 8 | url = ( 9 | 'http://w1.weather.gov/xml/current_obs/{}.xml' 10 | .format(station) 11 | ) 12 | response = urlopen(url) 13 | 14 | xmlroot = ElementTree.fromstring(response.read()) 15 | weatherdata = { 16 | 'observation_time_rfc822': None, 17 | 'temp_c': None, 18 | 'relative_humidity': None, 19 | 'pressure_mb': None, 20 | 'weather': None 21 | } 22 | 23 | for tag in weatherdata: 24 | element = xmlroot.find(tag) 25 | if element is not None: 26 | weatherdata[tag] = element.text 27 | 28 | return weatherdata 29 | 30 | 31 | def upload_to_corporate_rest( 32 | filepath, upload_url, auth_url, 33 | username, password): 34 | 35 | session = requests.session() 36 | 37 | response = session.post( 38 | auth_url, 39 | data={'username': username, 'password': password} 40 | ) 41 | response.raise_for_status() 42 | 43 | files = {'file': open(filepath, 'rb')} 44 | response = session.put( 45 | upload_url, 46 | files=files 47 | ) 48 | files['file'].close() 49 | response.raise_for_status() 50 | 51 | 52 | def upload_to_corporate_ftp( 53 | filepath, ftp_host, 54 | ftp_port, ftp_user, ftp_pass): 55 | 56 | with ftp.FTP() as ftp_cx: 57 | # connect and login 58 | ftp_cx.connect(ftp_host, ftp_port) 59 | ftp_cx.login(ftp_user, ftp_pass) 60 | 61 | # upload file 62 | filename = path.basename(filepath) 63 | 64 | with open(filepath, 'rb') as fh: 65 | ftp_cx.storbinary('STOR {}'.format(filename), fh) 66 | -------------------------------------------------------------------------------- /Chapter16/demoColorDialog.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoColorDialog.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(400, 176) 15 | self.frameColor = QtWidgets.QFrame(Dialog) 16 | self.frameColor.setGeometry(QtCore.QRect(210, 20, 120, 80)) 17 | font = QtGui.QFont() 18 | font.setPointSize(12) 19 | self.frameColor.setFont(font) 20 | self.frameColor.setFrameShape(QtWidgets.QFrame.StyledPanel) 21 | self.frameColor.setFrameShadow(QtWidgets.QFrame.Raised) 22 | self.frameColor.setObjectName("frameColor") 23 | self.pushButtonColor = QtWidgets.QPushButton(Dialog) 24 | self.pushButtonColor.setGeometry(QtCore.QRect(30, 40, 151, 23)) 25 | font = QtGui.QFont() 26 | font.setPointSize(12) 27 | self.pushButtonColor.setFont(font) 28 | self.pushButtonColor.setObjectName("pushButtonColor") 29 | self.labelColor = QtWidgets.QLabel(Dialog) 30 | self.labelColor.setGeometry(QtCore.QRect(30, 130, 351, 20)) 31 | font = QtGui.QFont() 32 | font.setPointSize(12) 33 | self.labelColor.setFont(font) 34 | self.labelColor.setText("") 35 | self.labelColor.setObjectName("labelColor") 36 | 37 | self.retranslateUi(Dialog) 38 | QtCore.QMetaObject.connectSlotsByName(Dialog) 39 | 40 | def retranslateUi(self, Dialog): 41 | _translate = QtCore.QCoreApplication.translate 42 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 43 | self.pushButtonColor.setText(_translate("Dialog", "Choose color")) 44 | 45 | -------------------------------------------------------------------------------- /Chapter19/callChangePassword.pyw: -------------------------------------------------------------------------------- 1 | import sqlite3, sys 2 | from PyQt5.QtWidgets import QDialog, QApplication 3 | from sqlite3 import Error 4 | 5 | from demoChangePassword import * 6 | 7 | class MyForm(QDialog): 8 | 9 | def __init__(self): 10 | super().__init__() 11 | self.ui = Ui_Dialog() 12 | self.ui.setupUi(self) 13 | self.ui.pushButtonChangePassword.clicked.connect(self.ChangePassword) 14 | self.show() 15 | 16 | def ChangePassword(self): 17 | selectStatement="SELECT EmailAddress, Password FROM Users where EmailAddress like '"+self.ui.lineEditEmailAddress.text()+"' and Password like '"+ self.ui.lineEditOldPassword.text()+"'" 18 | try: 19 | conn = sqlite3.connect("ECommerce.db") 20 | cur = conn.cursor() 21 | cur.execute(selectStatement) 22 | row = cur.fetchone() 23 | if row==None: 24 | self.ui.labelResponse.setText("Sorry, Incorrect email address or password ") 25 | else: 26 | if self.ui.lineEditNewPassword.text()== self.ui.lineEditRePassword.text(): 27 | updateStatement="UPDATE Users set Password = '" + self.ui.lineEditNewPassword.text()+"' WHERE EmailAddress like '"+self.ui.lineEditEmailAddress.text()+"'" 28 | with conn: 29 | cur.execute(updateStatement) 30 | self.ui.labelResponse.setText("Password successfully changed") 31 | else: 32 | self.ui.labelResponse.setText("The two passwords don't match") 33 | except Error as e: 34 | self.ui.labelResponse.setText("Error in accessing row") 35 | finally: 36 | conn.close() 37 | 38 | if __name__=="__main__": 39 | app = QApplication(sys.argv) 40 | w = MyForm() 41 | w.show() 42 | sys.exit(app.exec_()) 43 | -------------------------------------------------------------------------------- /Chapter13/callRadioButton2.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoRadioButton2 import * 6 | 7 | class MyForm(QDialog): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_Dialog() 11 | self.ui.setupUi(self) 12 | self.ui.radioButtonMedium.toggled.connect(self.dispSelected) 13 | self.ui.radioButtonLarge.toggled.connect(self.dispSelected) 14 | self.ui.radioButtonXL.toggled.connect(self.dispSelected) 15 | self.ui.radioButtonXXL.toggled.connect(self.dispSelected) 16 | self.ui.radioButtonDebitCard.toggled.connect(self.dispSelected) 17 | self.ui.radioButtonNetBanking.toggled.connect(self.dispSelected) 18 | self.ui.radioButtonCashOnDelivery.toggled.connect(self.dispSelected) 19 | self.show() 20 | 21 | def dispSelected(self): 22 | selected1=""; 23 | selected2="" 24 | if self.ui.radioButtonMedium.isChecked()==True: 25 | selected1="Medium" 26 | if self.ui.radioButtonLarge.isChecked()==True: 27 | selected1="Large" 28 | if self.ui.radioButtonXL.isChecked()==True: 29 | selected1="Extra Large" 30 | if self.ui.radioButtonXXL.isChecked()==True: 31 | selected1="Extra Extra Large" 32 | if self.ui.radioButtonDebitCard.isChecked()==True: 33 | selected2="Debit/Credit Card" 34 | if self.ui.radioButtonNetBanking.isChecked()==True: 35 | selected2="NetBanking" 36 | if self.ui.radioButtonCashOnDelivery.isChecked()==True: 37 | selected2="Cash On Delivery" 38 | self.ui.labelSelected.setText("Chosen shirt size is "+selected1+" and payment method as " + selected2) 39 | 40 | if __name__=="__main__": 41 | app = QApplication(sys.argv) 42 | w = MyForm() 43 | w.show() 44 | sys.exit(app.exec_()) 45 | -------------------------------------------------------------------------------- /Chapter05/rst_example.rst: -------------------------------------------------------------------------------- 1 | ================== 2 | This is the title 3 | ================== 4 | 5 | -------------------- 6 | This is a subtitle. 7 | -------------------- 8 | 9 | 10 | Heading 1 11 | ========= 12 | 13 | This is the first paragraph of the RST file. The great thing about RST is that it can be read as a plain text document, or interpretted by software into more attractive formats like HTML or PDF. 14 | 15 | The second paragraph starts here. The docutils project provides a set of scripts to convert rst into other formats, including: 16 | 17 | * HTML 18 | * PDF 19 | * ODT 20 | * XML 21 | 22 | 23 | Heading 2 24 | --------- 25 | 26 | This is a paragraph under heading 2. Let's add a block of code:: 27 | 28 | from tkinter import Tk, Label 29 | r = Tk() 30 | Label(r, 'Hi!').pack() 31 | r.mainloop() 32 | 33 | Here's a simple table: 34 | 35 | ================= =============================== 36 | Node Description 37 | ================= =============================== 38 | docs folder for documentation 39 | abq_data_entry folder for application module 40 | abq_data_entry.py main executable for application 41 | README.rst The basic documentation 42 | ================ =============================== 43 | 44 | Here's a more complex table: 45 | 46 | +-----------------+-------------------------------+ 47 | |Node |Description | 48 | +=================+===============================+ 49 | |docs |folder for documentation | 50 | +-----------------+-------------------------------+ 51 | |abq_data_entry |folder for application module | 52 | +-----------------+-------------------------------+ 53 | |abq_data_entry.py|main executable for application| 54 | +-----------------+-------------------------------+ 55 | |README.rst |The basic documentation | 56 | +-----------------+-------------------------------+ 57 | -------------------------------------------------------------------------------- /Chapter20/callDrawDiffLine.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | from PyQt5.QtGui import QPainter, QPen 5 | from PyQt5.QtCore import Qt 6 | 7 | from demoDrawDiffLine import * 8 | 9 | class MyForm(QDialog): 10 | def __init__(self): 11 | super().__init__() 12 | self.ui = Ui_Dialog() 13 | self.ui.setupUi(self) 14 | self.lineType="SolidLine" 15 | self.pos1 = [0,0] 16 | self.pos2 = [0,0] 17 | self.show() 18 | 19 | def paintEvent(self, event): 20 | qp = QPainter() 21 | qp.begin(self) 22 | pen = QPen(Qt.black, 4) 23 | self.lineTypeFormat="Qt."+self.lineType 24 | if self.lineTypeFormat == "Qt.SolidLine": 25 | pen.setStyle(Qt.SolidLine) 26 | elif self.lineTypeFormat == "Qt.DashLine": 27 | pen.setStyle(Qt.DashLine) 28 | elif self.lineTypeFormat =="Qt.DashDotLine": 29 | pen.setStyle(Qt.DashDotLine) 30 | elif self.lineTypeFormat =="Qt.DotLine": 31 | pen.setStyle(Qt.DotLine) 32 | elif self.lineTypeFormat =="Qt.DashDotDotLine": 33 | pen.setStyle(Qt.DashDotDotLine) 34 | qp.setPen(pen) 35 | qp.drawLine(self.pos1[0], self.pos1[1], self.pos2[0], self.pos2[1]) 36 | qp.end() 37 | 38 | def mousePressEvent(self, event): 39 | if event.buttons() & QtCore.Qt.LeftButton: 40 | self.pos1[0], self.pos1[1] = event.pos().x(), event.pos().y() 41 | 42 | def mouseReleaseEvent(self, event): 43 | self.lineType=self.ui.listWidgetLineType.currentItem().text() 44 | self.pos2[0], self.pos2[1] = event.pos().x(), event.pos().y() 45 | self.update() 46 | 47 | if __name__=="__main__": 48 | app = QApplication(sys.argv) 49 | w = MyForm() 50 | w.show() 51 | sys.exit(app.exec_()) 52 | -------------------------------------------------------------------------------- /Chapter16/demoColorDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 176 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 210 20 | 20 21 | 120 22 | 80 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | QFrame::StyledPanel 32 | 33 | 34 | QFrame::Raised 35 | 36 | 37 | 38 | 39 | 40 | 30 41 | 40 42 | 151 43 | 23 44 | 45 | 46 | 47 | 48 | 12 49 | 50 | 51 | 52 | Choose color 53 | 54 | 55 | 56 | 57 | 58 | 30 59 | 130 60 | 351 61 | 20 62 | 63 | 64 | 65 | 66 | 12 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /Chapter20/demoDrawDiffLine.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 527 10 | 409 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 10 21 | 481 22 | 51 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | Select the style from the list and then click and drag to draw a line 32 | 33 | 34 | 35 | 36 | 37 | 10 38 | 70 39 | 131 40 | 141 41 | 42 | 43 | 44 | 45 | 12 46 | 47 | 48 | 49 | 50 | SolidLine 51 | 52 | 53 | 54 | 55 | DashLine 56 | 57 | 58 | 59 | 60 | DashDotLine 61 | 62 | 63 | 64 | 65 | DotLine 66 | 67 | 68 | 69 | 70 | DashDotDotLine 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Chapter01/better_hello_tkinter.py: -------------------------------------------------------------------------------- 1 | """A better Hello World for Tkinter""" 2 | 3 | import tkinter as tk 4 | from tkinter import ttk 5 | 6 | 7 | class HelloView(tk.Frame): 8 | """A friendly little module""" 9 | 10 | def __init__(self, parent, *args, **kwargs): 11 | super().__init__(parent, *args, **kwargs) 12 | 13 | self.name = tk.StringVar() 14 | self.hello_string = tk.StringVar() 15 | self.hello_string.set("Hello World") 16 | 17 | name_label = ttk.Label(self, text="Name:") 18 | name_entry = ttk.Entry(self, textvariable=self.name) 19 | ch_button = ttk.Button(self, text="Change", command=self.on_change) 20 | hello_label = ttk.Label(self, textvariable=self.hello_string, 21 | font=("TkDefaultFont", 64), wraplength=600) 22 | 23 | # Layout form 24 | name_label.grid(row=0, column=0, sticky=tk.W) 25 | name_entry.grid(row=0, column=1, sticky=(tk.W + tk.E)) 26 | ch_button.grid(row=0, column=2, sticky=tk.E) 27 | hello_label.grid(row=1, column=0, columnspan=3) 28 | self.columnconfigure(1, weight=1) 29 | 30 | def on_change(self): 31 | """Handle Change button clicks""" 32 | if self.name.get().strip(): 33 | self.hello_string.set("Hello " + self.name.get()) 34 | else: 35 | self.hello_string.set("Hello World") 36 | 37 | 38 | class MyApplication(tk.Tk): 39 | """Hello World Main Application""" 40 | 41 | def __init__(self, *args, **kwargs): 42 | super().__init__(*args, **kwargs) 43 | 44 | # set the window properties 45 | self.title("Hello Tkinter") 46 | self.geometry("800x600") 47 | self.resizable(width=False, height=False) 48 | 49 | # Define the UI 50 | HelloView(self).grid(sticky=(tk.E + tk.W + tk.N + tk.S)) 51 | self.columnconfigure(0, weight=1) 52 | 53 | 54 | if __name__ == '__main__': 55 | app = MyApplication() 56 | app.mainloop() 57 | -------------------------------------------------------------------------------- /Chapter04/DateEntry.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | from datetime import datetime 4 | 5 | class DateEntry(ttk.Entry): 6 | """An Entry for ISO-style dates (Year-month-day)""" 7 | 8 | def __init__(self, parent, *args, **kwargs): 9 | super().__init__(parent, *args, **kwargs) 10 | self.config( 11 | validate='all', 12 | validatecommand=(self.register(self._validate), '%S', '%i', '%V', '%d'), 13 | invalidcommand=(self.register(self._on_invalid), '%V') 14 | ) 15 | self.error = tk.StringVar() 16 | 17 | def _toggle_error(self, error=''): 18 | self.error.set(error) 19 | if error: 20 | self.config(foreground='red') 21 | else: 22 | self.config(foreground='black') 23 | 24 | def _validate(self, char, index, event, action): 25 | 26 | # reset error state 27 | self._toggle_error() 28 | valid = True 29 | 30 | # ISO dates only need digits and hyphens 31 | if event == 'key': 32 | if action == '0': 33 | valid = True 34 | elif index in ('0', '1', '2', '3', '5', '6', '8', '9'): 35 | valid = char.isdigit() 36 | elif index in ('4', '7'): 37 | valid = char == '-' 38 | else: 39 | valid = False 40 | elif event == 'focusout': 41 | try: 42 | datetime.strptime(self.get(), '%Y-%m-%d') 43 | except ValueError: 44 | valid = False 45 | return valid 46 | 47 | def _on_invalid(self, event): 48 | if event != 'key': 49 | self._toggle_error('Not a valid date') 50 | 51 | if __name__ == '__main__': 52 | root = tk.Tk() 53 | entry = DateEntry(root) 54 | entry.pack() 55 | tk.Label(textvariable=entry.error).pack() 56 | 57 | # add this so we can unfocus the DateEntry 58 | tk.Entry(root).pack() 59 | root.mainloop() 60 | -------------------------------------------------------------------------------- /Chapter14/demoFontComboBox.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 552 10 | 228 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 20 21 | 231 22 | 41 23 | 24 | 25 | 26 | 27 | 14 28 | 29 | 30 | 31 | Select desired font 32 | 33 | 34 | 35 | 36 | 37 | 20 38 | 60 39 | 161 40 | 41 41 | 42 | 43 | 44 | 45 | 14 46 | 47 | 48 | 49 | Type some text 50 | 51 | 52 | 53 | 54 | 55 | 200 56 | 20 57 | 321 58 | 31 59 | 60 | 61 | 62 | 63 | 14 64 | 65 | 66 | 67 | 68 | 69 | 70 | 200 71 | 70 72 | 321 73 | 121 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Chapter20/demoMouseClicks.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoMouseClicks.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(565, 265) 15 | self.labelPress = QtWidgets.QLabel(Dialog) 16 | self.labelPress.setGeometry(QtCore.QRect(20, 60, 521, 20)) 17 | font = QtGui.QFont() 18 | font.setPointSize(12) 19 | self.labelPress.setFont(font) 20 | self.labelPress.setText("") 21 | self.labelPress.setObjectName("labelPress") 22 | self.labelRelease = QtWidgets.QLabel(Dialog) 23 | self.labelRelease.setGeometry(QtCore.QRect(20, 100, 521, 20)) 24 | font = QtGui.QFont() 25 | font.setPointSize(12) 26 | self.labelRelease.setFont(font) 27 | self.labelRelease.setText("") 28 | self.labelRelease.setObjectName("labelRelease") 29 | self.label = QtWidgets.QLabel(Dialog) 30 | self.label.setGeometry(QtCore.QRect(20, 10, 531, 51)) 31 | font = QtGui.QFont() 32 | font.setPointSize(12) 33 | self.label.setFont(font) 34 | self.label.setObjectName("label") 35 | 36 | self.retranslateUi(Dialog) 37 | QtCore.QMetaObject.connectSlotsByName(Dialog) 38 | 39 | def retranslateUi(self, Dialog): 40 | _translate = QtCore.QCoreApplication.translate 41 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 42 | self.label.setText(_translate("Dialog", "Displays the x, y co-ordinates where mouse button is pressed and released")) 43 | 44 | 45 | if __name__ == "__main__": 46 | import sys 47 | app = QtWidgets.QApplication(sys.argv) 48 | Dialog = QtWidgets.QDialog() 49 | ui = Ui_Dialog() 50 | ui.setupUi(Dialog) 51 | Dialog.show() 52 | sys.exit(app.exec_()) 53 | 54 | -------------------------------------------------------------------------------- /Chapter04/ValidatedSpinboxNoDynamic.py: -------------------------------------------------------------------------------- 1 | class ValidatedSpinbox(ValidatedMixin, tk.Spinbox): 2 | 3 | def __init__(self, *args, **kwargs): 4 | super().__init__(*args, **kwargs) 5 | 6 | self.min = Decimal(str(kwargs.get('from_', '-Infinity'))) 7 | self.max = Decimal(str(kwargs.get('to', 'Infinity'))) 8 | self.resolution = Decimal(str(kwargs.get('increment', '1.0'))) 9 | self.precision = self.resolution.normalize().as_tuple().exponent 10 | 11 | def _key_validate(self, char, index, current, proposed, action, **kwargs): 12 | valid = True 13 | 14 | no_negative = self.min >= 0 15 | no_decimal = self.precision >= 0 16 | 17 | if action == '0': 18 | return True 19 | 20 | # First, filter out obviously invalid keystrokes 21 | if any([ 22 | (char not in ('-1234567890.')), 23 | (char == '-' and (no_negative or index != '0')), 24 | (char == '.' and (no_decimal or '.' in current)) 25 | ]): 26 | return False 27 | 28 | # At this point, proposed is either '-', '.', '-.', 29 | # or a valid Decimal string 30 | if proposed in '-.': 31 | return True 32 | 33 | # Proposed is a valid Decimal string 34 | # convert to Decimal and check more: 35 | proposed = Decimal(proposed) 36 | proposed_precision = proposed.as_tuple().exponent 37 | 38 | if any([ 39 | (proposed > self.max), 40 | (proposed_precision < self.precision) 41 | ]): 42 | return False 43 | 44 | return valid 45 | 46 | def _focusout_validate(self, **kwargs): 47 | 48 | try: 49 | value = Decimal(self.get()) 50 | except InvalidOperation: 51 | self.error.set('Invalid number string') 52 | return False 53 | 54 | if value < self.min: 55 | self.error.set('Value is too low (min {})'.format(self.min)) 56 | return False 57 | 58 | return True 59 | -------------------------------------------------------------------------------- /Chapter14/demoSignalSlot1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoSignalSlot1.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(348, 453) 15 | self.lineEdit = QtWidgets.QLineEdit(Dialog) 16 | self.lineEdit.setGeometry(QtCore.QRect(90, 50, 181, 20)) 17 | self.lineEdit.setObjectName("lineEdit") 18 | self.pushButton = QtWidgets.QPushButton(Dialog) 19 | self.pushButton.setGeometry(QtCore.QRect(140, 160, 75, 23)) 20 | self.pushButton.setObjectName("pushButton") 21 | self.pushButton_2 = QtWidgets.QPushButton(Dialog) 22 | self.pushButton_2.setGeometry(QtCore.QRect(140, 260, 75, 23)) 23 | self.pushButton_2.setObjectName("pushButton_2") 24 | self.lineEdit_2 = QtWidgets.QLineEdit(Dialog) 25 | self.lineEdit_2.setGeometry(QtCore.QRect(90, 390, 181, 20)) 26 | self.lineEdit_2.setObjectName("lineEdit_2") 27 | 28 | self.retranslateUi(Dialog) 29 | self.pushButton.pressed.connect(self.lineEdit.selectAll) 30 | self.pushButton_2.clicked.connect(self.lineEdit_2.paste) 31 | self.pushButton.released.connect(self.lineEdit.copy) 32 | QtCore.QMetaObject.connectSlotsByName(Dialog) 33 | 34 | def retranslateUi(self, Dialog): 35 | _translate = QtCore.QCoreApplication.translate 36 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 37 | self.pushButton.setText(_translate("Dialog", "Copy")) 38 | self.pushButton_2.setText(_translate("Dialog", "Paste")) 39 | 40 | 41 | if __name__ == "__main__": 42 | import sys 43 | app = QtWidgets.QApplication(sys.argv) 44 | Dialog = QtWidgets.QDialog() 45 | ui = Ui_Dialog() 46 | ui.setupUi(Dialog) 47 | Dialog.show() 48 | sys.exit(app.exec_()) 49 | 50 | -------------------------------------------------------------------------------- /Chapter05/ABQ_Data_Entry/abq_data_entry/application.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import ttk 3 | from datetime import datetime 4 | from . import views as v 5 | from . import models as m 6 | 7 | 8 | class Application(tk.Tk): 9 | """Application root window""" 10 | 11 | def __init__(self, *args, **kwargs): 12 | super().__init__(*args, **kwargs) 13 | 14 | self.title("ABQ Data Entry Application") 15 | self.resizable(width=False, height=False) 16 | 17 | ttk.Label( 18 | self, 19 | text="ABQ Data Entry Application", 20 | font=("TkDefaultFont", 16) 21 | ).grid(row=0) 22 | 23 | 24 | self.recordform = v.DataRecordForm(self, m.CSVModel.fields) 25 | self.recordform.grid(row=1, padx=10) 26 | 27 | self.savebutton = ttk.Button(self, text="Save", command=self.on_save) 28 | self.savebutton.grid(sticky="e", row=2, padx=10) 29 | 30 | # status bar 31 | self.status = tk.StringVar() 32 | self.statusbar = ttk.Label(self, textvariable=self.status) 33 | self.statusbar.grid(sticky="we", row=3, padx=10) 34 | 35 | self.records_saved = 0 36 | 37 | def on_save(self): 38 | """Handles save button clicks""" 39 | 40 | # Check for errors first 41 | 42 | errors = self.recordform.get_errors() 43 | if errors: 44 | self.status.set( 45 | "Cannot save, error in fields: {}" 46 | .format(', '.join(errors.keys())) 47 | ) 48 | return False 49 | 50 | # For now, we save to a hardcoded filename with a datestring. 51 | datestring = datetime.today().strftime("%Y-%m-%d") 52 | filename = "abq_data_record_{}.csv".format(datestring) 53 | model = m.CSVModel(filename) 54 | data = self.recordform.get() 55 | model.save_record(data) 56 | self.records_saved += 1 57 | self.status.set( 58 | "{} records saved this session".format(self.records_saved) 59 | ) 60 | self.recordform.reset() 61 | -------------------------------------------------------------------------------- /Chapter14/demoProgressBar.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoProgressBar.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(350, 153) 15 | self.progressBar = QtWidgets.QProgressBar(Dialog) 16 | self.progressBar.setGeometry(QtCore.QRect(40, 60, 281, 23)) 17 | font = QtGui.QFont() 18 | font.setPointSize(12) 19 | self.progressBar.setFont(font) 20 | self.progressBar.setProperty("value", 0) 21 | self.progressBar.setObjectName("progressBar") 22 | self.label = QtWidgets.QLabel(Dialog) 23 | self.label.setGeometry(QtCore.QRect(80, 20, 181, 21)) 24 | font = QtGui.QFont() 25 | font.setPointSize(12) 26 | self.label.setFont(font) 27 | self.label.setObjectName("label") 28 | self.pushButtonStart = QtWidgets.QPushButton(Dialog) 29 | self.pushButtonStart.setGeometry(QtCore.QRect(80, 110, 151, 31)) 30 | font = QtGui.QFont() 31 | font.setPointSize(12) 32 | self.pushButtonStart.setFont(font) 33 | self.pushButtonStart.setObjectName("pushButtonStart") 34 | 35 | self.retranslateUi(Dialog) 36 | QtCore.QMetaObject.connectSlotsByName(Dialog) 37 | 38 | def retranslateUi(self, Dialog): 39 | _translate = QtCore.QCoreApplication.translate 40 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 41 | self.label.setText(_translate("Dialog", "Downloading the file")) 42 | self.pushButtonStart.setText(_translate("Dialog", "Start Downloading")) 43 | 44 | 45 | if __name__ == "__main__": 46 | import sys 47 | app = QtWidgets.QApplication(sys.argv) 48 | Dialog = QtWidgets.QDialog() 49 | ui = Ui_Dialog() 50 | ui.setupUi(Dialog) 51 | Dialog.show() 52 | sys.exit(app.exec_()) 53 | 54 | -------------------------------------------------------------------------------- /Chapter13/demoLineEdit.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoLineEdit.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(379, 195) 15 | self.label = QtWidgets.QLabel(Dialog) 16 | self.label.setGeometry(QtCore.QRect(6, 40, 121, 20)) 17 | font = QtGui.QFont() 18 | font.setPointSize(11) 19 | self.label.setFont(font) 20 | self.label.setObjectName("label") 21 | self.labelResponse = QtWidgets.QLabel(Dialog) 22 | self.labelResponse.setGeometry(QtCore.QRect(40, 90, 271, 20)) 23 | font = QtGui.QFont() 24 | font.setPointSize(11) 25 | self.labelResponse.setFont(font) 26 | self.labelResponse.setObjectName("labelResponse") 27 | self.lineEditName = QtWidgets.QLineEdit(Dialog) 28 | self.lineEditName.setGeometry(QtCore.QRect(140, 40, 201, 20)) 29 | font = QtGui.QFont() 30 | font.setPointSize(11) 31 | self.lineEditName.setFont(font) 32 | self.lineEditName.setObjectName("lineEditName") 33 | self.ButtonClickMe = QtWidgets.QPushButton(Dialog) 34 | self.ButtonClickMe.setGeometry(QtCore.QRect(160, 130, 101, 23)) 35 | font = QtGui.QFont() 36 | font.setPointSize(11) 37 | self.ButtonClickMe.setFont(font) 38 | self.ButtonClickMe.setObjectName("ButtonClickMe") 39 | 40 | self.retranslateUi(Dialog) 41 | QtCore.QMetaObject.connectSlotsByName(Dialog) 42 | 43 | def retranslateUi(self, Dialog): 44 | _translate = QtCore.QCoreApplication.translate 45 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 46 | self.label.setText(_translate("Dialog", "Enter your name")) 47 | self.labelResponse.setText(_translate("Dialog", "TextLabel")) 48 | self.ButtonClickMe.setText(_translate("Dialog", "Click")) 49 | 50 | -------------------------------------------------------------------------------- /Chapter15/LineEditClass.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoLineEdit.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(379, 195) 15 | self.label = QtWidgets.QLabel(Dialog) 16 | self.label.setGeometry(QtCore.QRect(6, 40, 121, 20)) 17 | font = QtGui.QFont() 18 | font.setPointSize(11) 19 | self.label.setFont(font) 20 | self.label.setObjectName("label") 21 | self.labelResponse = QtWidgets.QLabel(Dialog) 22 | self.labelResponse.setGeometry(QtCore.QRect(40, 90, 271, 20)) 23 | font = QtGui.QFont() 24 | font.setPointSize(11) 25 | self.labelResponse.setFont(font) 26 | self.labelResponse.setObjectName("labelResponse") 27 | self.lineEditName = QtWidgets.QLineEdit(Dialog) 28 | self.lineEditName.setGeometry(QtCore.QRect(140, 40, 201, 20)) 29 | font = QtGui.QFont() 30 | font.setPointSize(11) 31 | self.lineEditName.setFont(font) 32 | self.lineEditName.setObjectName("lineEditName") 33 | self.ButtonClickMe = QtWidgets.QPushButton(Dialog) 34 | self.ButtonClickMe.setGeometry(QtCore.QRect(160, 130, 101, 23)) 35 | font = QtGui.QFont() 36 | font.setPointSize(11) 37 | self.ButtonClickMe.setFont(font) 38 | self.ButtonClickMe.setObjectName("ButtonClickMe") 39 | 40 | self.retranslateUi(Dialog) 41 | QtCore.QMetaObject.connectSlotsByName(Dialog) 42 | 43 | def retranslateUi(self, Dialog): 44 | _translate = QtCore.QCoreApplication.translate 45 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 46 | self.label.setText(_translate("Dialog", "Enter your name")) 47 | self.labelResponse.setText(_translate("Dialog", "TextLabel")) 48 | self.ButtonClickMe.setText(_translate("Dialog", "Click")) 49 | 50 | -------------------------------------------------------------------------------- /Chapter14/demoListWidget3.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 734 10 | 270 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 20 21 | 191 22 | 16 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | Your favourite food item 32 | 33 | 34 | 35 | 36 | 37 | 210 38 | 20 39 | 201 40 | 20 41 | 42 | 43 | 44 | 45 | 12 46 | 47 | 48 | 49 | 50 | 51 | 52 | 110 53 | 72 54 | 111 55 | 31 56 | 57 | 58 | 59 | 60 | 12 61 | 62 | 63 | 64 | Add to List 65 | 66 | 67 | 68 | 69 | 70 | 430 71 | 20 72 | 256 73 | 221 74 | 75 | 76 | 77 | 78 | 12 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /Chapter20/callToolBars.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | from PyQt5.QtWidgets import QMainWindow, QApplication 3 | from PyQt5.QtGui import QPainter 4 | 5 | from demoToolBars import * 6 | 7 | class AppWindow(QMainWindow): 8 | def __init__(self): 9 | super().__init__() 10 | self.ui = Ui_MainWindow() 11 | self.ui.setupUi(self) 12 | self.pos1 = [0,0] 13 | self.pos2 = [0,0] 14 | self.toDraw="" 15 | self.ui.actionCircle.triggered.connect(self.drawCircle) 16 | self.ui.actionRectangle.triggered.connect(self.drawRectangle) 17 | self.ui.actionLine.triggered.connect(self.drawLine) 18 | self.show() 19 | 20 | def paintEvent(self, event): 21 | qp = QPainter() 22 | qp.begin(self) 23 | if self.toDraw=="rectangle": 24 | width = self.pos2[0]-self.pos1[0] 25 | height = self.pos2[1] - self.pos1[1] 26 | qp.drawRect(self.pos1[0], self.pos1[1], width, height) 27 | if self.toDraw=="line": 28 | qp.drawLine(self.pos1[0], self.pos1[1], self.pos2[0], self.pos2[1]) 29 | if self.toDraw=="circle": 30 | width = self.pos2[0]-self.pos1[0] 31 | height = self.pos2[1] - self.pos1[1] 32 | rect = QtCore.QRect(self.pos1[0], self.pos1[1], width, height) 33 | startAngle = 0 34 | arcLength = 360 *16 35 | qp.drawArc(rect, startAngle, arcLength) 36 | qp.end() 37 | 38 | def mousePressEvent(self, event): 39 | if event.buttons() & QtCore.Qt.LeftButton: 40 | self.pos1[0], self.pos1[1] = event.pos().x(), event.pos().y() 41 | 42 | def mouseReleaseEvent(self, event): 43 | self.pos2[0], self.pos2[1] = event.pos().x(), event.pos().y() 44 | self.update() 45 | 46 | def drawCircle(self): 47 | self.toDraw="circle" 48 | 49 | def drawRectangle(self): 50 | self.toDraw="rectangle" 51 | 52 | def drawLine(self): 53 | self.toDraw="line" 54 | 55 | app = QApplication(sys.argv) 56 | w = AppWindow() 57 | w.show() 58 | sys.exit(app.exec_()) 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Chapter15/callMultipleInheritance.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoMultipleInheritance import * 6 | 7 | class Student: 8 | name = "" 9 | code = "" 10 | 11 | def __init__(self, code, name): 12 | self.code = code 13 | self.name = name 14 | 15 | def getCode(self): 16 | return self.code 17 | 18 | def getName(self): 19 | return self.name 20 | 21 | 22 | class Marks: 23 | historyMarks = 0 24 | geographyMarks = 0 25 | 26 | def __init__(self, historyMarks, geographyMarks): 27 | self.historyMarks = historyMarks 28 | self.geographyMarks = geographyMarks 29 | 30 | def getHistoryMarks(self): 31 | return self.historyMarks 32 | 33 | def getGeographyMarks(self): 34 | return self.geographyMarks 35 | 36 | class Result(Student, Marks): 37 | totalMarks = 0 38 | percentage = 0 39 | 40 | def __init__(self, code, name, historyMarks, geographyMarks): 41 | Student.__init__(self, code, name) 42 | Marks.__init__(self, historyMarks, geographyMarks) 43 | self.totalMarks = historyMarks + geographyMarks 44 | self.percentage = (historyMarks + geographyMarks) / 200 * 100 45 | 46 | def getTotalMarks(self): 47 | return self.totalMarks 48 | 49 | def getPercentage(self): 50 | return self.percentage 51 | 52 | class MyForm(QDialog): 53 | def __init__(self): 54 | super().__init__() 55 | self.ui = Ui_Dialog() 56 | self.ui.setupUi(self) 57 | self.ui.ButtonClickMe.clicked.connect(self.dispmessage) 58 | self.show() 59 | 60 | def dispmessage(self): 61 | resultObj=Result(self.ui.lineEditCode.text(), self.ui.lineEditName.text(), int(self.ui.lineEditHistoryMarks.text()), int(self.ui.lineEditGeographyMarks.text())) 62 | self.ui.lineEditTotal.setText(str(resultObj.getTotalMarks())) 63 | self.ui.lineEditPercentage.setText(str(resultObj.getPercentage())) 64 | 65 | if __name__=="__main__": 66 | app = QApplication(sys.argv) 67 | w = MyForm() 68 | w.show() 69 | sys.exit(app.exec_()) 70 | -------------------------------------------------------------------------------- /Chapter14/demoFontComboBox.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoFontComboBox.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(560, 228) 15 | self.label = QtWidgets.QLabel(Dialog) 16 | self.label.setGeometry(QtCore.QRect(20, 20, 231, 41)) 17 | font = QtGui.QFont() 18 | font.setPointSize(14) 19 | self.label.setFont(font) 20 | self.label.setObjectName("label") 21 | self.labelTextLine = QtWidgets.QLabel(Dialog) 22 | self.labelTextLine.setGeometry(QtCore.QRect(20, 60, 161, 41)) 23 | font = QtGui.QFont() 24 | font.setPointSize(14) 25 | self.labelTextLine.setFont(font) 26 | self.labelTextLine.setObjectName("labelTextLine") 27 | self.fontComboBox = QtWidgets.QFontComboBox(Dialog) 28 | self.fontComboBox.setGeometry(QtCore.QRect(200, 20, 321, 31)) 29 | font = QtGui.QFont() 30 | font.setPointSize(14) 31 | self.fontComboBox.setFont(font) 32 | self.fontComboBox.setObjectName("fontComboBox") 33 | self.textEdit = QtWidgets.QTextEdit(Dialog) 34 | self.textEdit.setGeometry(QtCore.QRect(200, 70, 321, 121)) 35 | self.textEdit.setObjectName("textEdit") 36 | 37 | self.retranslateUi(Dialog) 38 | QtCore.QMetaObject.connectSlotsByName(Dialog) 39 | 40 | def retranslateUi(self, Dialog): 41 | _translate = QtCore.QCoreApplication.translate 42 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 43 | self.label.setText(_translate("Dialog", "Select desired font")) 44 | self.labelTextLine.setText(_translate("Dialog", "Type some text")) 45 | 46 | 47 | if __name__ == "__main__": 48 | import sys 49 | app = QtWidgets.QApplication(sys.argv) 50 | Dialog = QtWidgets.QDialog() 51 | ui = Ui_Dialog() 52 | ui.setupUi(Dialog) 53 | Dialog.show() 54 | sys.exit(app.exec_()) 55 | 56 | -------------------------------------------------------------------------------- /Chapter18/demoBrowser.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demoBrowser.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(563, 339) 15 | self.widget = QWebEngineView(Dialog) 16 | self.widget.setGeometry(QtCore.QRect(10, 60, 531, 251)) 17 | self.widget.setObjectName("widget") 18 | self.pushButtonGo = QtWidgets.QPushButton(Dialog) 19 | self.pushButtonGo.setGeometry(QtCore.QRect(450, 20, 91, 23)) 20 | font = QtGui.QFont() 21 | font.setPointSize(12) 22 | self.pushButtonGo.setFont(font) 23 | self.pushButtonGo.setObjectName("pushButtonGo") 24 | self.lineEditURL = QtWidgets.QLineEdit(Dialog) 25 | self.lineEditURL.setGeometry(QtCore.QRect(100, 20, 331, 21)) 26 | font = QtGui.QFont() 27 | font.setPointSize(12) 28 | self.lineEditURL.setFont(font) 29 | self.lineEditURL.setObjectName("lineEditURL") 30 | self.label = QtWidgets.QLabel(Dialog) 31 | self.label.setGeometry(QtCore.QRect(10, 20, 71, 16)) 32 | font = QtGui.QFont() 33 | font.setPointSize(12) 34 | self.label.setFont(font) 35 | self.label.setObjectName("label") 36 | 37 | self.retranslateUi(Dialog) 38 | QtCore.QMetaObject.connectSlotsByName(Dialog) 39 | 40 | def retranslateUi(self, Dialog): 41 | _translate = QtCore.QCoreApplication.translate 42 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 43 | self.pushButtonGo.setText(_translate("Dialog", "Go")) 44 | self.label.setText(_translate("Dialog", "Enter URL")) 45 | 46 | from PyQt5.QtWebEngineWidgets import QWebEngineView 47 | 48 | if __name__ == "__main__": 49 | import sys 50 | app = QtWidgets.QApplication(sys.argv) 51 | Dialog = QtWidgets.QDialog() 52 | ui = Ui_Dialog() 53 | ui.setupUi(Dialog) 54 | Dialog.show() 55 | sys.exit(app.exec_()) 56 | 57 | -------------------------------------------------------------------------------- /Chapter13/demoLineEdit.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 379 10 | 195 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 6 20 | 40 21 | 121 22 | 20 23 | 24 | 25 | 26 | 27 | 11 28 | 29 | 30 | 31 | Enter your name 32 | 33 | 34 | 35 | 36 | 37 | 40 38 | 90 39 | 271 40 | 20 41 | 42 | 43 | 44 | 45 | 11 46 | 47 | 48 | 49 | TextLabel 50 | 51 | 52 | 53 | 54 | 55 | 140 56 | 40 57 | 201 58 | 20 59 | 60 | 61 | 62 | 63 | 11 64 | 65 | 66 | 67 | 68 | 69 | 70 | 160 71 | 130 72 | 101 73 | 23 74 | 75 | 76 | 77 | 78 | 11 79 | 80 | 81 | 82 | Click 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /Chapter15/LineEditClass.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 379 10 | 195 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 6 20 | 40 21 | 121 22 | 20 23 | 24 | 25 | 26 | 27 | 11 28 | 29 | 30 | 31 | Enter your name 32 | 33 | 34 | 35 | 36 | 37 | 40 38 | 90 39 | 271 40 | 20 41 | 42 | 43 | 44 | 45 | 11 46 | 47 | 48 | 49 | TextLabel 50 | 51 | 52 | 53 | 54 | 55 | 140 56 | 40 57 | 201 58 | 20 59 | 60 | 61 | 62 | 63 | 11 64 | 65 | 66 | 67 | 68 | 69 | 70 | 160 71 | 130 72 | 101 73 | 23 74 | 75 | 76 | 77 | 78 | 11 79 | 80 | 81 | 82 | Click 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /Chapter15/callMultilevelInheritance.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PyQt5.QtWidgets import QDialog, QApplication 4 | 5 | from demoMultilevelInheritance import * 6 | 7 | class Student: 8 | name = "" 9 | code = "" 10 | 11 | def __init__(self, code, name): 12 | self.code = code 13 | self.name = name 14 | 15 | def getCode(self): 16 | return self.code 17 | 18 | def getName(self): 19 | return self.name 20 | 21 | 22 | class Marks(Student): 23 | historyMarks = 0 24 | geographyMarks = 0 25 | 26 | def __init__(self, code, name, historyMarks, geographyMarks): 27 | Student.__init__(self,code,name) 28 | self.historyMarks = historyMarks 29 | self.geographyMarks = geographyMarks 30 | 31 | def getHistoryMarks(self): 32 | return self.historyMarks 33 | 34 | def getGeographyMarks(self): 35 | return self.geographyMarks 36 | 37 | class Result(Marks): 38 | totalMarks = 0 39 | percentage = 0 40 | 41 | def __init__(self, code, name, historyMarks, geographyMarks): 42 | Marks.__init__(self, code, name, historyMarks, geographyMarks) 43 | self.totalMarks = historyMarks + geographyMarks 44 | self.percentage = (historyMarks + geographyMarks) / 200 * 100 45 | 46 | def getTotalMarks(self): 47 | return self.totalMarks 48 | 49 | def getPercentage(self): 50 | return self.percentage 51 | 52 | class MyForm(QDialog): 53 | def __init__(self): 54 | super().__init__() 55 | self.ui = Ui_Dialog() 56 | self.ui.setupUi(self) 57 | self.ui.ButtonClickMe.clicked.connect(self.dispmessage) 58 | self.show() 59 | 60 | def dispmessage(self): 61 | resultObj=Result(self.ui.lineEditCode.text(), self.ui.lineEditName.text(), int(self.ui.lineEditHistoryMarks.text()), int(self.ui.lineEditGeographyMarks.text())) 62 | self.ui.lineEditTotal.setText(str(resultObj.getTotalMarks())) 63 | self.ui.lineEditPercentage.setText(str(resultObj.getPercentage())) 64 | 65 | if __name__=="__main__": 66 | app = QApplication(sys.argv) 67 | w = MyForm() 68 | w.show() 69 | sys.exit(app.exec_()) 70 | -------------------------------------------------------------------------------- /Chapter19/demoDatabase.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 453 10 | 159 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 10 20 | 20 21 | 151 22 | 20 23 | 24 | 25 | 26 | 27 | 12 28 | 29 | 30 | 31 | Enter database name 32 | 33 | 34 | 35 | 36 | 37 | 180 38 | 20 39 | 241 40 | 20 41 | 42 | 43 | 44 | 45 | 12 46 | 47 | 48 | 49 | 50 | 51 | 52 | 160 53 | 70 54 | 141 55 | 23 56 | 57 | 58 | 59 | 60 | 12 61 | 62 | 63 | 64 | Create Database 65 | 66 | 67 | 68 | 69 | 70 | 40 71 | 120 72 | 391 73 | 20 74 | 75 | 76 | 77 | 78 | 12 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /Chapter14/demoComboBox.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 674 10 | 200 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 260 20 | 40 21 | 361 22 | 31 23 | 24 | 25 | 26 | 27 | 14 28 | 29 | 30 | 31 | 32 | Saving Account 33 | 34 | 35 | 36 | 37 | Current Account 38 | 39 | 40 | 41 | 42 | Recurring Deposit Account 43 | 44 | 45 | 46 | 47 | Fixed Deposit Account 48 | 49 | 50 | 51 | 52 | 53 | 54 | 20 55 | 40 56 | 231 57 | 31 58 | 59 | 60 | 61 | 62 | 14 63 | 64 | 65 | 66 | Select your account type 67 | 68 | 69 | 70 | 71 | 72 | 40 73 | 110 74 | 581 75 | 41 76 | 77 | 78 | 79 | 80 | 14 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | --------------------------------------------------------------------------------