Добрый день, жители Хабро!
Введение
В свободное время я увлекся написанием приложений на PyQt5. И мой давний проект по домашней бухгалтерии Мой бумажник В конце мая я решил переписать его с плюсов на Python, так как предыдущая версия имела ряд архитектурных ошибок, исправлять которые мне не хотелось.Поэтому, скомпилировав PyQt5 из исходников для Fedora 21, я примерно за две недели реализовал весь ранее доступный функционал.
И теперь возникает вопрос визуализации ежемесячных данных о расходах/доходах.
Поскольку у меня был опыт визуализации данных с использованием QCustomPlot , я хотел сделать визуализацию с помощью этой библиотеки.
Но, к сожалению, никаких привязок я не нашел.
Сборка
После просмотра исходного кода PyQt5 было обнаружено, что генерация привязок реализована с помощью ГЛОТОК ).SIP принимает на вход что-то вроде урезанного заголовка методов класса (разумеется, с его так называемыми аннотациями), а на выходе генерирует C++-код для создания готового Python-модуля.
Итак, для сборки модуля QCustomPlot для Python нам понадобится:
- Qt 5.x.
- SIP последней версии.
- PyQt 5.x.
- Скомпилировано как динамически подключаемая библиотека qcustomplot, скомпилированная для Qt 5.x.
- Специальный тип файла, описывающий интерфейс классов библиотеки.
Убедимся, что всё получилось, запустим IPy:$ python3 configure.py build $ make $ sudo make install
$ python3
>>> import qcustomplot
>>> dir(qcustomplot)
['QCP', 'QCPAbstractItem', 'QCPAbstractLegendItem', 'QCPAbstractPlottable', 'QCPAxis', 'QCPAxisRect', 'QCPBarData', 'QCPBars', 'QCPBarsGroup', 'QCPColorGradient', 'QCPColorMap', 'QCPColorMapData', 'QCPColorScale', 'QCPColorScaleAxisRectPrivate', 'QCPCurve', 'QCPCurveData', 'QCPData', 'QCPFinancial', 'QCPFinancialData', 'QCPGraph', 'QCPGrid', 'QCPItemAnchor', 'QCPItemBracket', 'QCPItemCurve', 'QCPItemEllipse', 'QCPItemLine', 'QCPItemPixmap', 'QCPItemPosition', 'QCPItemRect', 'QCPItemStraightLine', 'QCPItemText', 'QCPItemTracer', 'QCPLayer', 'QCPLayerable', 'QCPLayout', 'QCPLayoutElement', 'QCPLayoutGrid', 'QCPLayoutInset', 'QCPLegend', 'QCPLineEnding', 'QCPMarginGroup', 'QCPPainter', 'QCPPlotTitle', 'QCPPlottableLegendItem', 'QCPRange', 'QCPScatterStyle', 'QCPStatisticalBox', 'QCustomPlot', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
>>>
Ну а чтобы было действительно красиво, приведу код одного из примеров БарыДемо : Пример кода
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QColor, QPen
from qcustomplot import QCustomPlot, QCPBars, QCP
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QCustomPlot()
regen = QCPBars(w.xAxis, w.yAxis)
nuclear = QCPBars(w.xAxis, w.yAxis)
fossil = QCPBars(w.xAxis, w.yAxis)
w.addPlottable(regen)
w.addPlottable(nuclear)
w.addPlottable(fossil)
pen = QPen()
pen.setWidthF(1.2)
fossil.setName('Fossil fuels')
pen.setColor(QColor(255, 131, 0))
fossil.setPen(pen)
fossil.setBrush(QColor(255, 131, 0, 50))
nuclear.setName('Nuclear')
pen.setColor(QColor(1, 92, 192))
nuclear.setPen(pen)
nuclear.setBrush(QColor(1, 92, 191, 50))
regen.setName('Regenerative')
pen.setColor(QColor(150, 222, 0))
regen.setPen(pen)
regen.setBrush(QColor(150, 222, 0, 70))
nuclear.moveAbove(fossil)
regen.moveAbove(nuclear)
ticks = [1, 2, 3, 4, 5, 6, 7]
labels = ['USA', 'Japan', 'Germany', 'France', 'UK', 'Italy', 'Canada']
w.xAxis.setAutoTicks(False)
w.xAxis.setAutoTickLabels(False)
w.xAxis.setTickVector(ticks)
w.xAxis.setTickVectorLabels(labels)
w.xAxis.setTickLabelRotation(60)
w.xAxis.setSubTickCount(0)
w.xAxis.grid().
setVisible(True)
w.xAxis.setRange(0, 8)
w.yAxis.setRange(0, 12.1)
w.yAxis.setPadding(5)
w.yAxis.setLabel('Power Consumption in\nKilowatts per Capita (2007)')
w.yAxis.grid().
setSubGridVisible(True)
grid_pen = QPen()
grid_pen.setStyle(Qt.SolidLine)
grid_pen.setColor(QColor(0, 0, 0, 25))
w.yAxis.grid().
setSubGridPen(grid_pen)
fossil_data = [0.86 * 10.5, 0.83 * 5.5, 0.84 * 5.5, 0.52 * 5.8, 0.89 * 5.2, 0.90 * 4.2, 0.67 * 11.2]
nuclear_data = [0.08 * 10.5, 0.12 * 5.5, 0.12 * 5.5, 0.40 * 5.8, 0.09 * 5.2, 0.00 * 4.2, 0.07 * 11.2]
regen_data = [0.06 * 10.5, 0.05 * 5.5, 0.04 * 5.5, 0.06 * 5.8, 0.02 * 5.2, 0.07 * 4.2, 0.25 * 11.2]
fossil.setData(ticks, fossil_data)
nuclear.setData(ticks, nuclear_data)
regen.setData(ticks, regen_data)
w.legend.setVisible(True)
w.axisRect().
insetLayout().
setInsetAlignment(0, Qt.AlignTop|Qt.AlignHCenter)
w.legend.setBrush(QColor(255, 255, 255, 200))
legendPen = QPen()
legendPen.setColor(QColor(130, 130, 130, 200))
w.legend.setBorderPen(legendPen)
w.setInteractions(QCP.iRangeDrag or QCP.iRangeZoom)
w.show()
sys.exit(app.exec())
Вот что произошло: Результат
P.S.
Ссылка на репозиторий с исходниками: QCustomPlot-PyQt5 .Репозиторий в каталоге RPMS содержит SRPM и RPM для Fedora21 (PyQt5, qcustomplot 1.3.1 и python3-qcustomplot).
Все комментарии и предложения приветствуются.
Надеюсь, вы найдете этот модуль полезным.
Спасибо за внимание! Теги: #qt5 python PyQt5 #python #C++ #Qt
-
Компьютерщики И Садовые Гномы
19 Oct, 24 -
Сергей Брин Женился На Бывшей Коллеге
19 Oct, 24