├── .gitignore.txt
├── 2016-07-30_qt_matplotlib_sine_scroll
├── LICENSE.md
├── README.md
├── demo.gif
├── go.bat
├── go.py
├── matplotlibwidget.py
├── ui_convert.py
├── ui_main.py
└── ui_main.ui
├── 2016-07-31_qt_PyQtGraph_sine_scroll
├── LICENSE.md
├── README.md
├── demo2.gif
├── go.bat
├── go.py
├── ui_convert.py
├── ui_main.py
└── ui_main.ui
├── 2016-07-37_qt_audio_monitor
├── LICENSE.rc
├── README.md
├── SWHear.py
├── demo.gif
├── go.py
├── ui_convert.py
├── ui_main.py
└── ui_main.ui
├── 2017-06-10_python27_qt4
├── demo.png
├── readme.md
├── run.cmd
├── run.py
├── ui2py.py
├── ui2py.pyc
├── ui_main.py
├── ui_main.pyc
└── ui_main.ui
├── 2019-02-03_pyQtGraph
├── pyQtGraph-example.py
├── readme.md
└── screenshot.PNG
├── LICENSE
└── README.md
/.gitignore.txt:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 |
27 | # PyInstaller
28 | # Usually these files are written by a python script from a template
29 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
30 | *.manifest
31 | *.spec
32 |
33 | # Installer logs
34 | pip-log.txt
35 | pip-delete-this-directory.txt
36 |
37 | # Unit test / coverage reports
38 | htmlcov/
39 | .tox/
40 | .coverage
41 | .coverage.*
42 | .cache
43 | nosetests.xml
44 | coverage.xml
45 | *,cover
46 | .hypothesis/
47 |
48 | # Translations
49 | *.mo
50 | *.pot
51 |
52 | # Django stuff:
53 | *.log
54 | local_settings.py
55 |
56 | # Flask stuff:
57 | instance/
58 | .webassets-cache
59 |
60 | # Scrapy stuff:
61 | .scrapy
62 |
63 | # Sphinx documentation
64 | docs/_build/
65 |
66 | # PyBuilder
67 | target/
68 |
69 | # IPython Notebook
70 | .ipynb_checkpoints
71 |
72 | # pyenv
73 | .python-version
74 |
75 | # celery beat schedule file
76 | celerybeat-schedule
77 |
78 | # dotenv
79 | .env
80 |
81 | # virtualenv
82 | venv/
83 | ENV/
84 |
85 | # Spyder project settings
86 | .spyderproject
87 |
88 | # Rope project settings
89 | .ropeproject
90 |
--------------------------------------------------------------------------------
/2016-07-30_qt_matplotlib_sine_scroll/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) [2016] [Scott W Harden]
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.
--------------------------------------------------------------------------------
/2016-07-30_qt_matplotlib_sine_scroll/README.md:
--------------------------------------------------------------------------------
1 | # Matplotlib MatplotlibWidget demo
2 | This was tested to be ~40x SLOWER than a similar pyqtgraph graph
3 |
4 | PROJECT PAGE: http://www.swharden.com/wp/2016-07-30-live-data-in-pyqt4-with-matplotlibwidget/
5 |
6 | This is a minimal-case example how to get a PyQt4 GUI (designed with QT Designer) to display a matploblit widget and update it automatically. This was tested with the WinPython 3.x distribution, but should be cross platform. Read the parent readme for full project details.
7 |
8 | * edit the ui_main.ui with "Qt Designer"
9 | * run ui_convert.py to turn ui_main.ui into ui_main.py
10 | * run go.py to launch the program (pulling UI from ui_main.py)
11 | * if the "keep updating" box is checked and the add buttin is hit, it does more and more!
12 |
13 | 
14 |
15 | ### Misc notes
16 | If you get `ImportError: No module named 'matplotlibwidget'`, ensure you are in the same folder as `matplotlibwidget.py` which is now provided with this example.
--------------------------------------------------------------------------------
/2016-07-30_qt_matplotlib_sine_scroll/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swharden/Python-GUI-examples/a6f9e86f890267f96a6011803652741716d2d2d5/2016-07-30_qt_matplotlib_sine_scroll/demo.gif
--------------------------------------------------------------------------------
/2016-07-30_qt_matplotlib_sine_scroll/go.bat:
--------------------------------------------------------------------------------
1 | python go.py
2 | pause
--------------------------------------------------------------------------------
/2016-07-30_qt_matplotlib_sine_scroll/go.py:
--------------------------------------------------------------------------------
1 | from PyQt4 import QtGui,QtCore
2 | import sys
3 | import ui_main
4 | import numpy as np
5 | import pylab
6 | import time
7 |
8 | class ExampleApp(QtGui.QMainWindow, ui_main.Ui_MainWindow):
9 | def __init__(self, parent=None):
10 | super(ExampleApp, self).__init__(parent)
11 | self.setupUi(self)
12 | self.btnAdd.clicked.connect(self.update)
13 | self.matplotlibwidget.axes.hold(False) #clear on plot()
14 |
15 | def update(self):
16 | t1=time.time()
17 | points=100 #number of data points
18 | X=np.arange(points)
19 | Y=np.sin(np.arange(points)/points*3*np.pi+time.time())
20 | C=pylab.cm.jet(time.time()%10/10) # random color
21 | self.matplotlibwidget.axes.plot(X,Y,ms=100,color=C,lw=10,alpha=.8)
22 | self.matplotlibwidget.axes.grid()
23 | self.matplotlibwidget.axes.get_figure().tight_layout() # fill space
24 | self.matplotlibwidget.draw() # required to update the window
25 | print("update took %.02f ms"%((time.time()-t1)*1000))
26 | if self.chkMore.isChecked():
27 | QtCore.QTimer.singleShot(10, self.update) # QUICKLY repeat
28 |
29 | if __name__=="__main__":
30 | app = QtGui.QApplication(sys.argv)
31 | form = ExampleApp()
32 | form.show()
33 | form.update() #start with something
34 | app.exec_()
35 | print("DONE")
--------------------------------------------------------------------------------
/2016-07-30_qt_matplotlib_sine_scroll/matplotlibwidget.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Copyright © 2009 Pierre Raybaut
4 | # Licensed under the terms of the MIT License
5 |
6 | """
7 | MatplotlibWidget
8 | ================
9 |
10 | Example of matplotlib widget for PyQt4
11 |
12 | Copyright © 2009 Pierre Raybaut
13 | This software is licensed under the terms of the MIT License
14 |
15 | Derived from 'embedding_in_pyqt4.py':
16 | Copyright © 2005 Florent Rougon, 2006 Darren Dale
17 | """
18 |
19 | __version__ = "1.0.0"
20 |
21 | from PyQt4.QtGui import QSizePolicy
22 | from PyQt4.QtCore import QSize
23 |
24 | from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as Canvas
25 | from matplotlib.figure import Figure
26 |
27 | from matplotlib import rcParams
28 | rcParams['font.size'] = 9
29 |
30 |
31 | class MatplotlibWidget(Canvas):
32 | """
33 | MatplotlibWidget inherits PyQt4.QtGui.QWidget
34 | and matplotlib.backend_bases.FigureCanvasBase
35 |
36 | Options: option_name (default_value)
37 | -------
38 | parent (None): parent widget
39 | title (''): figure title
40 | xlabel (''): X-axis label
41 | ylabel (''): Y-axis label
42 | xlim (None): X-axis limits ([min, max])
43 | ylim (None): Y-axis limits ([min, max])
44 | xscale ('linear'): X-axis scale
45 | yscale ('linear'): Y-axis scale
46 | width (4): width in inches
47 | height (3): height in inches
48 | dpi (100): resolution in dpi
49 | hold (False): if False, figure will be cleared each time plot is called
50 |
51 | Widget attributes:
52 | -----------------
53 | figure: instance of matplotlib.figure.Figure
54 | axes: figure axes
55 |
56 | Example:
57 | -------
58 | self.widget = MatplotlibWidget(self, yscale='log', hold=True)
59 | from numpy import linspace
60 | x = linspace(-10, 10)
61 | self.widget.axes.plot(x, x**2)
62 | self.wdiget.axes.plot(x, x**3)
63 | """
64 | def __init__(self, parent=None, title='', xlabel='', ylabel='',
65 | xlim=None, ylim=None, xscale='linear', yscale='linear',
66 | width=4, height=3, dpi=100, hold=False):
67 | self.figure = Figure(figsize=(width, height), dpi=dpi)
68 | self.axes = self.figure.add_subplot(111)
69 | self.axes.set_title(title)
70 | self.axes.set_xlabel(xlabel)
71 | self.axes.set_ylabel(ylabel)
72 | if xscale is not None:
73 | self.axes.set_xscale(xscale)
74 | if yscale is not None:
75 | self.axes.set_yscale(yscale)
76 | if xlim is not None:
77 | self.axes.set_xlim(*xlim)
78 | if ylim is not None:
79 | self.axes.set_ylim(*ylim)
80 | self.axes.hold(hold)
81 |
82 | Canvas.__init__(self, self.figure)
83 | self.setParent(parent)
84 |
85 | Canvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
86 | Canvas.updateGeometry(self)
87 |
88 | def sizeHint(self):
89 | w, h = self.get_width_height()
90 | return QSize(w, h)
91 |
92 | def minimumSizeHint(self):
93 | return QSize(10, 10)
94 |
95 |
96 |
97 | #===============================================================================
98 | # Example
99 | #===============================================================================
100 | if __name__ == '__main__':
101 | import sys
102 | from PyQt4.QtGui import QMainWindow, QApplication
103 | from numpy import linspace
104 |
105 | class ApplicationWindow(QMainWindow):
106 | def __init__(self):
107 | QMainWindow.__init__(self)
108 | self.mplwidget = MatplotlibWidget(self, title='Example',
109 | xlabel='Linear scale',
110 | ylabel='Log scale',
111 | hold=True, yscale='log')
112 | self.mplwidget.setFocus()
113 | self.setCentralWidget(self.mplwidget)
114 | self.plot(self.mplwidget.axes)
115 |
116 | def plot(self, axes):
117 | x = linspace(-10, 10)
118 | axes.plot(x, x**2)
119 | axes.plot(x, x**3)
120 |
121 | app = QApplication(sys.argv)
122 | win = ApplicationWindow()
123 | win.show()
124 | sys.exit(app.exec_())
125 |
--------------------------------------------------------------------------------
/2016-07-30_qt_matplotlib_sine_scroll/ui_convert.py:
--------------------------------------------------------------------------------
1 | from PyQt4 import uic
2 | import glob
3 | for fname in glob.glob("*.ui"):
4 | print("converting",fname)
5 | fin = open(fname,'r')
6 | fout = open(fname.replace(".ui",".py"),'w')
7 | uic.compileUi(fin,fout,execute=False)
8 | fin.close()
9 | fout.close()
10 |
--------------------------------------------------------------------------------
/2016-07-30_qt_matplotlib_sine_scroll/ui_main.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Form implementation generated from reading ui file 'ui_main.ui'
4 | #
5 | # Created by: PyQt4 UI code generator 4.11.4
6 | #
7 | # WARNING! All changes made in this file will be lost!
8 |
9 | from PyQt4 import QtCore, QtGui
10 |
11 | try:
12 | _fromUtf8 = QtCore.QString.fromUtf8
13 | except AttributeError:
14 | def _fromUtf8(s):
15 | return s
16 |
17 | try:
18 | _encoding = QtGui.QApplication.UnicodeUTF8
19 | def _translate(context, text, disambig):
20 | return QtGui.QApplication.translate(context, text, disambig, _encoding)
21 | except AttributeError:
22 | def _translate(context, text, disambig):
23 | return QtGui.QApplication.translate(context, text, disambig)
24 |
25 | class Ui_MainWindow(object):
26 | def setupUi(self, MainWindow):
27 | MainWindow.setObjectName(_fromUtf8("MainWindow"))
28 | MainWindow.resize(820, 650)
29 | MainWindow.setAutoFillBackground(False)
30 | MainWindow.setDocumentMode(False)
31 | self.centralwidget = QtGui.QWidget(MainWindow)
32 | self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
33 | self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
34 | self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
35 | self.horizontalLayout = QtGui.QHBoxLayout()
36 | self.horizontalLayout.setContentsMargins(-1, -1, 0, 0)
37 | self.horizontalLayout.setSpacing(10)
38 | self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
39 | self.btnAdd = QtGui.QPushButton(self.centralwidget)
40 | self.btnAdd.setObjectName(_fromUtf8("btnAdd"))
41 | self.horizontalLayout.addWidget(self.btnAdd)
42 | self.chkMore = QtGui.QCheckBox(self.centralwidget)
43 | self.chkMore.setObjectName(_fromUtf8("chkMore"))
44 | self.horizontalLayout.addWidget(self.chkMore)
45 | self.verticalLayout.addLayout(self.horizontalLayout)
46 | self.matplotlibwidget = MatplotlibWidget(self.centralwidget)
47 | self.matplotlibwidget.setObjectName(_fromUtf8("matplotlibwidget"))
48 | self.verticalLayout.addWidget(self.matplotlibwidget)
49 | MainWindow.setCentralWidget(self.centralwidget)
50 | self.statusbar = QtGui.QStatusBar(MainWindow)
51 | self.statusbar.setObjectName(_fromUtf8("statusbar"))
52 | MainWindow.setStatusBar(self.statusbar)
53 |
54 | self.retranslateUi(MainWindow)
55 | QtCore.QMetaObject.connectSlotsByName(MainWindow)
56 |
57 | def retranslateUi(self, MainWindow):
58 | MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
59 | self.btnAdd.setText(_translate("MainWindow", "update sine wave", None))
60 | self.chkMore.setText(_translate("MainWindow", "keep updating", None))
61 |
62 | from matplotlibwidget import MatplotlibWidget
63 |
--------------------------------------------------------------------------------
/2016-07-30_qt_matplotlib_sine_scroll/ui_main.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 820
10 | 650
11 |
12 |
13 |
14 | MainWindow
15 |
16 |
17 | false
18 |
19 |
20 | false
21 |
22 |
23 |
24 | -
25 |
26 |
27 | 10
28 |
29 |
30 | 0
31 |
32 |
33 | 0
34 |
35 |
-
36 |
37 |
38 | update sine wave
39 |
40 |
41 |
42 | -
43 |
44 |
45 | keep updating
46 |
47 |
48 |
49 |
50 |
51 | -
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | MatplotlibWidget
61 | QWidget
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/2016-07-31_qt_PyQtGraph_sine_scroll/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) [2016] [Scott W Harden]
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.
--------------------------------------------------------------------------------
/2016-07-31_qt_PyQtGraph_sine_scroll/README.md:
--------------------------------------------------------------------------------
1 | # PyQtGraph GraphWidget demo
2 | This was tested to be ~40x faster than a similar matplotlib graph
3 |
4 | PROJECT PAGE: http://www.swharden.com/wp/2016-07-31-live-data-in-pyqt4-with-plotwidget/
5 |
6 | This is a minimal-case example how to get a PyQt4 GUI (designed with QT Designer) to display a
7 | pyqtgraph PlotWidget and update it automatically. This was tested with the WinPython 3.x distribution,
8 | but should be cross platform. Read the parent readme for full project details.
9 |
10 | * edit the ui_main.ui with "Qt Designer"
11 | * run ui_convert.py to turn ui_main.ui into ui_main.py
12 | * run go.py to launch the program (pulling UI from ui_main.py)
13 | * if the "keep updating" box is checked and the add buttin is hit, it does more and more!
14 |
15 | 
16 |
--------------------------------------------------------------------------------
/2016-07-31_qt_PyQtGraph_sine_scroll/demo2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swharden/Python-GUI-examples/a6f9e86f890267f96a6011803652741716d2d2d5/2016-07-31_qt_PyQtGraph_sine_scroll/demo2.gif
--------------------------------------------------------------------------------
/2016-07-31_qt_PyQtGraph_sine_scroll/go.bat:
--------------------------------------------------------------------------------
1 | python go.py
2 | pause
--------------------------------------------------------------------------------
/2016-07-31_qt_PyQtGraph_sine_scroll/go.py:
--------------------------------------------------------------------------------
1 | from PyQt4 import QtGui,QtCore
2 | import sys
3 | import ui_main
4 | import numpy as np
5 | import pylab
6 | import time
7 | import pyqtgraph
8 |
9 | class ExampleApp(QtGui.QMainWindow, ui_main.Ui_MainWindow):
10 | def __init__(self, parent=None):
11 | pyqtgraph.setConfigOption('background', 'w') #before loading widget
12 | super(ExampleApp, self).__init__(parent)
13 | self.setupUi(self)
14 | self.btnAdd.clicked.connect(self.update)
15 | self.grPlot.plotItem.showGrid(True, True, 0.7)
16 |
17 | def update(self):
18 | t1=time.clock()
19 | points=100 #number of data points
20 | X=np.arange(points)
21 | Y=np.sin(np.arange(points)/points*3*np.pi+time.time())
22 | C=pyqtgraph.hsvColor(time.time()/5%1,alpha=.5)
23 | pen=pyqtgraph.mkPen(color=C,width=10)
24 | self.grPlot.plot(X,Y,pen=pen,clear=True)
25 | print("update took %.02f ms"%((time.clock()-t1)*1000))
26 | if self.chkMore.isChecked():
27 | QtCore.QTimer.singleShot(1, self.update) # QUICKLY repeat
28 |
29 | if __name__=="__main__":
30 | app = QtGui.QApplication(sys.argv)
31 | form = ExampleApp()
32 | form.show()
33 | form.update() #start with something
34 | app.exec_()
35 | print("DONE")
--------------------------------------------------------------------------------
/2016-07-31_qt_PyQtGraph_sine_scroll/ui_convert.py:
--------------------------------------------------------------------------------
1 | from PyQt4 import uic
2 | import glob
3 | for fname in glob.glob("*.ui"):
4 | print("converting",fname)
5 | fin = open(fname,'r')
6 | fout = open(fname.replace(".ui",".py"),'w')
7 | uic.compileUi(fin,fout,execute=False)
8 | fin.close()
9 | fout.close()
10 |
--------------------------------------------------------------------------------
/2016-07-31_qt_PyQtGraph_sine_scroll/ui_main.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Form implementation generated from reading ui file 'ui_main.ui'
4 | #
5 | # Created by: PyQt4 UI code generator 4.11.4
6 | #
7 | # WARNING! All changes made in this file will be lost!
8 |
9 | from PyQt4 import QtCore, QtGui
10 |
11 | try:
12 | _fromUtf8 = QtCore.QString.fromUtf8
13 | except AttributeError:
14 | def _fromUtf8(s):
15 | return s
16 |
17 | try:
18 | _encoding = QtGui.QApplication.UnicodeUTF8
19 | def _translate(context, text, disambig):
20 | return QtGui.QApplication.translate(context, text, disambig, _encoding)
21 | except AttributeError:
22 | def _translate(context, text, disambig):
23 | return QtGui.QApplication.translate(context, text, disambig)
24 |
25 | class Ui_MainWindow(object):
26 | def setupUi(self, MainWindow):
27 | MainWindow.setObjectName(_fromUtf8("MainWindow"))
28 | MainWindow.resize(820, 650)
29 | MainWindow.setAutoFillBackground(False)
30 | MainWindow.setDocumentMode(False)
31 | self.centralwidget = QtGui.QWidget(MainWindow)
32 | self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
33 | self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
34 | self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
35 | self.horizontalLayout = QtGui.QHBoxLayout()
36 | self.horizontalLayout.setContentsMargins(-1, -1, 0, 0)
37 | self.horizontalLayout.setSpacing(10)
38 | self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
39 | self.btnAdd = QtGui.QPushButton(self.centralwidget)
40 | self.btnAdd.setObjectName(_fromUtf8("btnAdd"))
41 | self.horizontalLayout.addWidget(self.btnAdd)
42 | self.chkMore = QtGui.QCheckBox(self.centralwidget)
43 | self.chkMore.setObjectName(_fromUtf8("chkMore"))
44 | self.horizontalLayout.addWidget(self.chkMore)
45 | self.verticalLayout.addLayout(self.horizontalLayout)
46 | self.grPlot = PlotWidget(self.centralwidget)
47 | self.grPlot.setObjectName(_fromUtf8("grPlot"))
48 | self.verticalLayout.addWidget(self.grPlot)
49 | MainWindow.setCentralWidget(self.centralwidget)
50 | self.statusbar = QtGui.QStatusBar(MainWindow)
51 | self.statusbar.setObjectName(_fromUtf8("statusbar"))
52 | MainWindow.setStatusBar(self.statusbar)
53 |
54 | self.retranslateUi(MainWindow)
55 | QtCore.QMetaObject.connectSlotsByName(MainWindow)
56 |
57 | def retranslateUi(self, MainWindow):
58 | MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
59 | self.btnAdd.setText(_translate("MainWindow", "update sine wave", None))
60 | self.chkMore.setText(_translate("MainWindow", "keep updating", None))
61 |
62 | from pyqtgraph import PlotWidget
63 |
--------------------------------------------------------------------------------
/2016-07-31_qt_PyQtGraph_sine_scroll/ui_main.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 820
10 | 650
11 |
12 |
13 |
14 | MainWindow
15 |
16 |
17 | false
18 |
19 |
20 | false
21 |
22 |
23 |
24 | -
25 |
26 |
27 | 10
28 |
29 |
30 | 0
31 |
32 |
33 | 0
34 |
35 |
-
36 |
37 |
38 | update sine wave
39 |
40 |
41 |
42 | -
43 |
44 |
45 | keep updating
46 |
47 |
48 |
49 |
50 |
51 | -
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | PlotWidget
61 | QGraphicsView
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/2016-07-37_qt_audio_monitor/LICENSE.rc:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Scott W Harden
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.
--------------------------------------------------------------------------------
/2016-07-37_qt_audio_monitor/README.md:
--------------------------------------------------------------------------------
1 |
2 | # qt audio monitor
3 |
4 | PROJECT PAGE: http://www.swharden.com/wp/2016-07-31-real-time-audio-monitor-with-pyqt/
5 |
6 | This is a minimal-case example how to get continuous PCM data from the sound card. A preliminary SWHEar class is included which can self-detect likely input devices. To manually define an input device, set it when SWHEar() is called. In most cases it will work right out of the box. If you're playing music and no microphone is detected, it will use the sound mapper and graph the audio being played.
7 |
8 | Youtube demo: https://youtu.be/lDS9rI0o6mM
9 |
10 | 
11 |
12 | ### Setup
13 | * pyaudio (which requires [portaudio](http://portaudio.com/)) comes ready to use if you install Anaconda
14 | * I did have to `conda install pyqtgraph pyaudio`
15 |
16 | ### Input overflow error?
17 | If you experience _[Errno -9981] Input overflowed_ errors, consider modifying [this line](https://github.com/swharden/Python-GUI-examples/blob/master/2016-07-37_qt_audio_monitor/SWHear.py#L119) and change:
18 | ```python
19 | self.stream.read(self.chunk)
20 | ```
21 | to:
22 | ```python
23 | self.stream.read(self.chunk, exception_on_overflow=False)
24 | ```
25 |
--------------------------------------------------------------------------------
/2016-07-37_qt_audio_monitor/SWHear.py:
--------------------------------------------------------------------------------
1 | """
2 | this is a stripped down version of the SWHear class.
3 | It's designed to hold only a single audio sample in memory.
4 | check my githib for a more complete version:
5 | http://github.com/swharden
6 | """
7 |
8 | import pyaudio
9 | import time
10 | import numpy as np
11 | import threading
12 |
13 | def getFFT(data,rate):
14 | """Given some data and rate, returns FFTfreq and FFT (half)."""
15 | data=data*np.hamming(len(data))
16 | fft=np.fft.fft(data)
17 | fft=np.abs(fft)
18 | #fft=10*np.log10(fft)
19 | freq=np.fft.fftfreq(len(fft),1.0/rate)
20 | return freq[:int(len(freq)/2)],fft[:int(len(fft)/2)]
21 |
22 | class SWHear():
23 | """
24 | The SWHear class is provides access to continuously recorded
25 | (and mathematically processed) microphone data.
26 |
27 | Arguments:
28 |
29 | device - the number of the sound card input to use. Leave blank
30 | to automatically detect one.
31 |
32 | rate - sample rate to use. Defaults to something supported.
33 |
34 | updatesPerSecond - how fast to record new data. Note that smaller
35 | numbers allow more data to be accessed and therefore high
36 | frequencies to be analyzed if using a FFT later
37 | """
38 |
39 | def __init__(self,device=None,rate=None,updatesPerSecond=10):
40 | self.p=pyaudio.PyAudio()
41 | self.chunk=4096 # gets replaced automatically
42 | self.updatesPerSecond=updatesPerSecond
43 | self.chunksRead=0
44 | self.device=device
45 | self.rate=rate
46 |
47 | ### SYSTEM TESTS
48 |
49 | def valid_low_rate(self,device):
50 | """set the rate to the lowest supported audio rate."""
51 | for testrate in [44100]:
52 | if self.valid_test(device,testrate):
53 | return testrate
54 | print("SOMETHING'S WRONG! I can't figure out how to use DEV",device)
55 | return None
56 |
57 | def valid_test(self,device,rate=44100):
58 | """given a device ID and a rate, return TRUE/False if it's valid."""
59 | try:
60 | self.info=self.p.get_device_info_by_index(device)
61 | if not self.info["maxInputChannels"]>0:
62 | return False
63 | stream=self.p.open(format=pyaudio.paInt16,channels=1,
64 | input_device_index=device,frames_per_buffer=self.chunk,
65 | rate=int(self.info["defaultSampleRate"]),input=True)
66 | stream.close()
67 | return True
68 | except:
69 | return False
70 |
71 | def valid_input_devices(self):
72 | """
73 | See which devices can be opened for microphone input.
74 | call this when no PyAudio object is loaded.
75 | """
76 | mics=[]
77 | for device in range(self.p.get_device_count()):
78 | if self.valid_test(device):
79 | mics.append(device)
80 | if len(mics)==0:
81 | print("no microphone devices found!")
82 | else:
83 | print("found %d microphone devices: %s"%(len(mics),mics))
84 | return mics
85 |
86 | ### SETUP AND SHUTDOWN
87 |
88 | def initiate(self):
89 | """run this after changing settings (like rate) before recording"""
90 | if self.device is None:
91 | self.device=self.valid_input_devices()[0] #pick the first one
92 | if self.rate is None:
93 | self.rate=self.valid_low_rate(self.device)
94 | self.chunk = int(self.rate/self.updatesPerSecond) # hold one tenth of a second in memory
95 | if not self.valid_test(self.device,self.rate):
96 | print("guessing a valid microphone device/rate...")
97 | self.device=self.valid_input_devices()[0] #pick the first one
98 | self.rate=self.valid_low_rate(self.device)
99 | self.datax=np.arange(self.chunk)/float(self.rate)
100 | msg='recording from "%s" '%self.info["name"]
101 | msg+='(device %d) '%self.device
102 | msg+='at %d Hz'%self.rate
103 | print(msg)
104 |
105 | def close(self):
106 | """gently detach from things."""
107 | print(" -- sending stream termination command...")
108 | self.keepRecording=False #the threads should self-close
109 | while(self.t.isAlive()): #wait for all threads to close
110 | time.sleep(.1)
111 | self.stream.stop_stream()
112 | self.p.terminate()
113 |
114 | ### STREAM HANDLING
115 |
116 | def stream_readchunk(self):
117 | """reads some audio and re-launches itself"""
118 | try:
119 | self.data = np.fromstring(self.stream.read(self.chunk),dtype=np.int16)
120 | self.fftx, self.fft = getFFT(self.data,self.rate)
121 |
122 | except Exception as E:
123 | print(" -- exception! terminating...")
124 | print(E,"\n"*5)
125 | self.keepRecording=False
126 | if self.keepRecording:
127 | self.stream_thread_new()
128 | else:
129 | self.stream.close()
130 | self.p.terminate()
131 | print(" -- stream STOPPED")
132 | self.chunksRead+=1
133 |
134 | def stream_thread_new(self):
135 | self.t=threading.Thread(target=self.stream_readchunk)
136 | self.t.start()
137 |
138 | def stream_start(self):
139 | """adds data to self.data until termination signal"""
140 | self.initiate()
141 | print(" -- starting stream")
142 | self.keepRecording=True # set this to False later to terminate stream
143 | self.data=None # will fill up with threaded recording data
144 | self.fft=None
145 | self.dataFiltered=None #same
146 | self.stream=self.p.open(format=pyaudio.paInt16,channels=1,
147 | rate=self.rate,input=True,frames_per_buffer=self.chunk)
148 | self.stream_thread_new()
149 |
150 | if __name__=="__main__":
151 | ear=SWHear(updatesPerSecond=10) # optinoally set sample rate here
152 | ear.stream_start() #goes forever
153 | lastRead=ear.chunksRead
154 | while True:
155 | while lastRead==ear.chunksRead:
156 | time.sleep(.01)
157 | print(ear.chunksRead,len(ear.data))
158 | lastRead=ear.chunksRead
159 | print("DONE")
160 |
--------------------------------------------------------------------------------
/2016-07-37_qt_audio_monitor/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swharden/Python-GUI-examples/a6f9e86f890267f96a6011803652741716d2d2d5/2016-07-37_qt_audio_monitor/demo.gif
--------------------------------------------------------------------------------
/2016-07-37_qt_audio_monitor/go.py:
--------------------------------------------------------------------------------
1 | from PyQt5 import QtGui,QtCore
2 |
3 | import sys
4 | import ui_main
5 | import numpy as np
6 | import pyqtgraph
7 | import SWHear
8 |
9 | class ExampleApp(QtGui.QMainWindow, ui_main.Ui_MainWindow):
10 | def __init__(self, parent=None):
11 | pyqtgraph.setConfigOption('background', 'w') #before loading widget
12 | super(ExampleApp, self).__init__(parent)
13 | self.setupUi(self)
14 | self.grFFT.plotItem.showGrid(True, True, 0.7)
15 | self.grPCM.plotItem.showGrid(True, True, 0.7)
16 | self.maxFFT=0
17 | self.maxPCM=0
18 | self.ear = SWHear.SWHear(rate=44100,updatesPerSecond=20)
19 | self.ear.stream_start()
20 |
21 | def update(self):
22 | if not self.ear.data is None and not self.ear.fft is None:
23 | pcmMax=np.max(np.abs(self.ear.data))
24 | if pcmMax>self.maxPCM:
25 | self.maxPCM=pcmMax
26 | self.grPCM.plotItem.setRange(yRange=[-pcmMax,pcmMax])
27 | if np.max(self.ear.fft)>self.maxFFT:
28 | self.maxFFT=np.max(np.abs(self.ear.fft))
29 | #self.grFFT.plotItem.setRange(yRange=[0,self.maxFFT])
30 | self.grFFT.plotItem.setRange(yRange=[0,1])
31 | self.pbLevel.setValue(1000*pcmMax/self.maxPCM)
32 | pen=pyqtgraph.mkPen(color='b')
33 | self.grPCM.plot(self.ear.datax,self.ear.data,pen=pen,clear=True)
34 | pen=pyqtgraph.mkPen(color='r')
35 | self.grFFT.plot(self.ear.fftx,self.ear.fft/self.maxFFT,pen=pen,clear=True)
36 | QtCore.QTimer.singleShot(1, self.update) # QUICKLY repeat
37 |
38 | if __name__=="__main__":
39 | app = QtGui.QApplication(sys.argv)
40 | form = ExampleApp()
41 | form.show()
42 | form.update() #start with something
43 | app.exec_()
44 | print("DONE")
45 |
--------------------------------------------------------------------------------
/2016-07-37_qt_audio_monitor/ui_convert.py:
--------------------------------------------------------------------------------
1 | from PyQt5 import uic
2 | import glob
3 | for fname in glob.glob("*.ui"):
4 | print("converting",fname)
5 | fin = open(fname,'r')
6 | fout = open(fname.replace(".ui",".py"),'w')
7 | uic.compileUi(fin,fout,execute=False)
8 | fin.close()
9 | fout.close()
10 |
--------------------------------------------------------------------------------
/2016-07-37_qt_audio_monitor/ui_main.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Form implementation generated from reading ui file 'ui_main.ui'
4 | #
5 | # Created by: PyQt4 UI code generator 4.11.4
6 | #
7 | # WARNING! All changes made in this file will be lost!
8 |
9 | from PyQt5 import QtCore, QtGui
10 |
11 | try:
12 | _fromUtf8 = QtCore.QString.fromUtf8
13 | except AttributeError:
14 | def _fromUtf8(s):
15 | return s
16 |
17 | try:
18 | _encoding = QtGui.QApplication.UnicodeUTF8
19 | def _translate(context, text, disambig):
20 | return QtGui.QApplication.translate(context, text, disambig, _encoding)
21 | except AttributeError:
22 | def _translate(context, text, disambig):
23 | return QtGui.QApplication.translate(context, text, disambig)
24 |
25 | class Ui_MainWindow(object):
26 | def setupUi(self, MainWindow):
27 | MainWindow.setObjectName(_fromUtf8("MainWindow"))
28 | MainWindow.resize(993, 692)
29 | self.centralwidget = QtGui.QWidget(MainWindow)
30 | self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
31 | self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
32 | self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
33 | self.pbLevel = QtGui.QProgressBar(self.centralwidget)
34 | self.pbLevel.setMaximum(1000)
35 | self.pbLevel.setProperty("value", 123)
36 | self.pbLevel.setTextVisible(False)
37 | self.pbLevel.setOrientation(QtCore.Qt.Vertical)
38 | self.pbLevel.setObjectName(_fromUtf8("pbLevel"))
39 | self.horizontalLayout.addWidget(self.pbLevel)
40 | self.frame = QtGui.QFrame(self.centralwidget)
41 | self.frame.setFrameShape(QtGui.QFrame.NoFrame)
42 | self.frame.setFrameShadow(QtGui.QFrame.Plain)
43 | self.frame.setObjectName(_fromUtf8("frame"))
44 | self.verticalLayout = QtGui.QVBoxLayout(self.frame)
45 | self.verticalLayout.setContentsMargins(0,0,0,0)
46 | self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
47 | self.label = QtGui.QLabel(self.frame)
48 | self.label.setObjectName(_fromUtf8("label"))
49 | self.verticalLayout.addWidget(self.label)
50 | self.grFFT = PlotWidget(self.frame)
51 | self.grFFT.setObjectName(_fromUtf8("grFFT"))
52 | self.verticalLayout.addWidget(self.grFFT)
53 | self.label_2 = QtGui.QLabel(self.frame)
54 | self.label_2.setObjectName(_fromUtf8("label_2"))
55 | self.verticalLayout.addWidget(self.label_2)
56 | self.grPCM = PlotWidget(self.frame)
57 | self.grPCM.setObjectName(_fromUtf8("grPCM"))
58 | self.verticalLayout.addWidget(self.grPCM)
59 | self.horizontalLayout.addWidget(self.frame)
60 | MainWindow.setCentralWidget(self.centralwidget)
61 |
62 | self.retranslateUi(MainWindow)
63 | QtCore.QMetaObject.connectSlotsByName(MainWindow)
64 |
65 | def retranslateUi(self, MainWindow):
66 | MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
67 | self.label.setText(_translate("MainWindow", "frequency data (FFT):", None))
68 | self.label_2.setText(_translate("MainWindow", "raw data (PCM):", None))
69 |
70 | from pyqtgraph import PlotWidget
71 |
--------------------------------------------------------------------------------
/2016-07-37_qt_audio_monitor/ui_main.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 993
10 | 692
11 |
12 |
13 |
14 | MainWindow
15 |
16 |
17 |
18 | -
19 |
20 |
21 | 1000
22 |
23 |
24 | 123
25 |
26 |
27 | false
28 |
29 |
30 | Qt::Vertical
31 |
32 |
33 |
34 | -
35 |
36 |
37 | QFrame::NoFrame
38 |
39 |
40 | QFrame::Plain
41 |
42 |
43 |
44 | 0
45 |
46 |
-
47 |
48 |
49 | frequency data (FFT):
50 |
51 |
52 |
53 | -
54 |
55 |
56 | -
57 |
58 |
59 | raw data (PCM):
60 |
61 |
62 |
63 | -
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | PlotWidget
75 | QGraphicsView
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/2017-06-10_python27_qt4/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swharden/Python-GUI-examples/a6f9e86f890267f96a6011803652741716d2d2d5/2017-06-10_python27_qt4/demo.png
--------------------------------------------------------------------------------
/2017-06-10_python27_qt4/readme.md:
--------------------------------------------------------------------------------
1 | # Live MatplotlibWidget with PyQt4 / Python 2.7
2 | The Python 2.7 PyQt4 toolsets are quite complete. WinPython 2.7 comes with QtDesigner and MatplotlibWidget out of the box. This project is a good starting point for a data visualization project for these platforms.
3 |
4 | ## Summary
5 | * in UI designer add a MatplotlibWidget and save as `ui_main.ui`
6 | * run ui2py.py to convert `ui_main.ui` -> `ui_main.py`
7 | * create a file like `run.py` and at the top import the ui with `import ui_main`
8 | * write some code to interact with the UI (look at the source code for details)
9 | * key lines for transparent matplotlib window (with transparent background and transparent frame):
10 |
11 | ```
12 | self.matplotlibwidget.axes.set_axis_bgcolor('none') # make a transparent graph background
13 | self.matplotlibwidget.figure.set_facecolor('none') # make a transparent frame background
14 | ```
15 |
16 | ## Output
17 |
18 | 
--------------------------------------------------------------------------------
/2017-06-10_python27_qt4/run.cmd:
--------------------------------------------------------------------------------
1 | "C:\Users\scott\Documents\important\WinPython\WinPython-64bit-2.7.10.3\python-2.7.10.amd64\python.exe" run.py
2 | pause
--------------------------------------------------------------------------------
/2017-06-10_python27_qt4/run.py:
--------------------------------------------------------------------------------
1 | from PyQt4 import QtGui,QtCore
2 | import sys
3 | import ui_main
4 | import numpy as np
5 | import pylab
6 | import time
7 |
8 | class ExampleApp(QtGui.QMainWindow, ui_main.Ui_MainWindow):
9 | def __init__(self, parent=None):
10 | super(ExampleApp, self).__init__(parent)
11 | self.setupUi(self)
12 | #self.btnAdd.clicked.connect(self.update)
13 | self.matplotlibwidget.axes.hold(False) #clear on plot()
14 | self.matplotlibwidget.axes.set_axis_bgcolor('none') # make a transparent graph background
15 | self.matplotlibwidget.figure.set_facecolor('none') # make a transparent frame background
16 |
17 | def update(self):
18 | t1=time.time()
19 | nPoints=100 #number of data points
20 | Xs=np.arange(nPoints)+time.time()*3 # make an X axis
21 | Ys=np.sin(Xs/8) # add some slowly moving data
22 | Xs-=Xs[0] # make X-axis start at 0
23 | self.matplotlibwidget.axes.plot(Xs,Ys,alpha=.5,lw=2)
24 | self.matplotlibwidget.axes.grid()
25 | self.matplotlibwidget.axes.margins(0,0.1)
26 | self.matplotlibwidget.axes.get_figure().tight_layout() # fill space
27 | self.matplotlibwidget.draw() # required to update the window
28 | print("update took %.02f ms"%((time.time()-t1)*1000))
29 | QtCore.QTimer.singleShot(100, self.update) # QUICKLY repeat
30 |
31 | if __name__=="__main__":
32 | app = QtGui.QApplication(sys.argv)
33 | form = ExampleApp()
34 | form.show()
35 | form.update() #start with something
36 | app.exec_()
37 | print("DONE")
--------------------------------------------------------------------------------
/2017-06-10_python27_qt4/ui2py.py:
--------------------------------------------------------------------------------
1 | # run this program to convert .ui files into .py files
2 | from PyQt4 import uic
3 | import glob
4 | for fname in glob.glob("*.ui"):
5 | print("converting",fname)
6 | fin = open(fname,'r')
7 | fout = open(fname.replace(".ui",".py"),'w')
8 | uic.compileUi(fin,fout,execute=False)
9 | fin.close()
10 | fout.close()
--------------------------------------------------------------------------------
/2017-06-10_python27_qt4/ui2py.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swharden/Python-GUI-examples/a6f9e86f890267f96a6011803652741716d2d2d5/2017-06-10_python27_qt4/ui2py.pyc
--------------------------------------------------------------------------------
/2017-06-10_python27_qt4/ui_main.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Form implementation generated from reading ui file 'ui_main.ui'
4 | #
5 | # Created by: PyQt4 UI code generator 4.11.4
6 | #
7 | # WARNING! All changes made in this file will be lost!
8 |
9 | from PyQt4 import QtCore, QtGui
10 |
11 | try:
12 | _fromUtf8 = QtCore.QString.fromUtf8
13 | except AttributeError:
14 | def _fromUtf8(s):
15 | return s
16 |
17 | try:
18 | _encoding = QtGui.QApplication.UnicodeUTF8
19 | def _translate(context, text, disambig):
20 | return QtGui.QApplication.translate(context, text, disambig, _encoding)
21 | except AttributeError:
22 | def _translate(context, text, disambig):
23 | return QtGui.QApplication.translate(context, text, disambig)
24 |
25 | class Ui_MainWindow(object):
26 | def setupUi(self, MainWindow):
27 | MainWindow.setObjectName(_fromUtf8("MainWindow"))
28 | MainWindow.resize(800, 600)
29 | self.centralwidget = QtGui.QWidget(MainWindow)
30 | self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
31 | self.gridLayout = QtGui.QGridLayout(self.centralwidget)
32 | self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
33 | self.matplotlibwidget = MatplotlibWidget(self.centralwidget)
34 | self.matplotlibwidget.setObjectName(_fromUtf8("matplotlibwidget"))
35 | self.gridLayout.addWidget(self.matplotlibwidget, 0, 0, 1, 1)
36 | MainWindow.setCentralWidget(self.centralwidget)
37 |
38 | self.retranslateUi(MainWindow)
39 | QtCore.QMetaObject.connectSlotsByName(MainWindow)
40 |
41 | def retranslateUi(self, MainWindow):
42 | MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
43 |
44 | from matplotlibwidget import MatplotlibWidget
45 |
--------------------------------------------------------------------------------
/2017-06-10_python27_qt4/ui_main.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swharden/Python-GUI-examples/a6f9e86f890267f96a6011803652741716d2d2d5/2017-06-10_python27_qt4/ui_main.pyc
--------------------------------------------------------------------------------
/2017-06-10_python27_qt4/ui_main.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 800
10 | 600
11 |
12 |
13 |
14 | MainWindow
15 |
16 |
17 |
18 | -
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | MatplotlibWidget
27 | QWidget
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/2019-02-03_pyQtGraph/pyQtGraph-example.py:
--------------------------------------------------------------------------------
1 | """
2 | Minimal-case example how to launch a standalone, interactive, pyqtgraph
3 |
4 | First install pyqtgraph with:
5 | pip install --upgrade pyqtgraph
6 | """
7 | import pyqtgraph as pg
8 | import pyqtgraph.exporters
9 | import numpy as np
10 |
11 | # set the styling of pyqtgraph
12 | pg.setConfigOption('background', 'w')
13 | pg.setConfigOption('foreground', 'k')
14 |
15 | # create some data
16 | pointCount = 1000
17 | xs = np.arange(pointCount)/pointCount*np.pi*2*5
18 | ys = np.sin(xs)
19 |
20 | # add noise
21 | ys += np.random.random_sample(len(ys))/10
22 |
23 | # create plot
24 | plt = pg.plot(xs, ys, title="Example PyQtGraph", pen='r')
25 | plt.showGrid(x=True,y=True)
26 |
27 | ## Start Qt event loop.
28 | if __name__ == '__main__':
29 | import sys
30 | if sys.flags.interactive != 1 or not hasattr(pg.QtCore, 'PYQT_VERSION'):
31 | pg.QtGui.QApplication.exec_()
--------------------------------------------------------------------------------
/2019-02-03_pyQtGraph/readme.md:
--------------------------------------------------------------------------------
1 | This project demonstrates how to use the standalone `pyqtgraph` library (http://www.pyqtgraph.org/) with Python 3 to launch an interactive plot with a set of X/Y data.
2 |
3 | Unlike other projects in this repository, this one doesn't require the user to set up a GUI (like a GTK/Glade-centric projects do). This is a great alternative to [matplotlib](https://matplotlib.org/) when the goal is to rapidly display and manipulate high density data.
4 |
5 | ## Installation
6 | ```
7 | pip install --upgrade pyqtgraph
8 | ```
9 |
10 | ## Example Code
11 |
12 | ```python
13 | import pyqtgraph as pg
14 | import pyqtgraph.exporters
15 | import numpy as np
16 |
17 | # set the styling of pyqtgraph
18 | pg.setConfigOption('background', 'w')
19 | pg.setConfigOption('foreground', 'k')
20 |
21 | # create some data
22 | pointCount = 1000
23 | xs = np.arange(pointCount)/pointCount*np.pi*2*5
24 | ys = np.sin(xs)
25 |
26 | # add noise
27 | ys += np.random.random_sample(len(ys))/10
28 |
29 | # create plot
30 | plt = pg.plot(xs, ys, title="Example PyQtGraph", pen='r')
31 | plt.showGrid(x=True,y=True)
32 |
33 | ## Start Qt event loop.
34 | if __name__ == '__main__':
35 | import sys
36 | if sys.flags.interactive != 1 or not hasattr(pg.QtCore, 'PYQT_VERSION'):
37 | pg.QtGui.QApplication.exec_()
38 | ```
39 |
40 | ## Screenshot
41 | 
--------------------------------------------------------------------------------
/2019-02-03_pyQtGraph/screenshot.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swharden/Python-GUI-examples/a6f9e86f890267f96a6011803652741716d2d2d5/2019-02-03_pyQtGraph/screenshot.PNG
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Scott W Harden
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Python-GUI-examples
2 | This repository is a collection of minimal-case examples for performing common GUI-related tasks in python. Emphasis is placed on tasks involving linear data plotting, image processing, and audio/frequency analysis.
3 |
4 | Description | Screenshot
5 | ---|---
6 | [scrolling live data with PlotWidget](2016-07-31_qt_PyQtGraph_sine_scroll) - extremely high speed graphing designed for realtime updates in GUI applications |
7 | [PyQt4 scrolling live data with MatplotlibWidget](2016-07-30_qt_matplotlib_sine_scroll) - pretty graphs with the MatPlotLib library (which many people already know how to use), but likely too slow for realtime / interactive graphing |
8 | [live PCM and FFT plotting with QtGraph](https://github.com/swharden/Python-GUI-examples/tree/master/2016-07-37_qt_audio_monitor) (based on PlotWidget) |
9 | [quick and simple pyqtgraph example](2019-02-03_pyQtGraph) to launch an interactive chart starting with a set of X/Y data |
10 | ### Useful Links:
11 | * [working with UI files](https://github.com/awesomebytes/python_qt_tutorial/blob/master/README.md#script-the-behaviour)
12 |
--------------------------------------------------------------------------------