Проблема с графиком pyqtgraph, PyQt5
Имеется код:
import sys
from datetime import datetime
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QWidget, QLabel
from PyQt5 import uic
from PyQt5.QtWidgets import QMainWindow
from PyQt5 import QtCore, QtWidgets
from PyQt5.Qt import *
from docxtpl import DocxTemplate
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg
class TimeAxisItem(pg.AxisItem):
def tickStrings(self, values, scale, spacing):
print(values, '\n', scale, '\n', spacing)
return [datetime.fromtimestamp(value) for value in values]
class Widget(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi("graph.ui", self)
# Добавить/удалить строку в tableWidget_2
# self.pushButton_7.clicked.connect(self.buttonAdd)
# self.pushButton_8.clicked.connect(self.buttonDelete)
# Добавить/удалить строку в tableWidget_3
self.pushButton_9.clicked.connect(self.buttonAdd_2)
self.pushButton_10.clicked.connect(self.buttonDelete_2)
# Сохранить данные из таблицы tableWidget_3
# self.pushButton.clicked.connect(self.buttonSave)
# Создания графиков (Ph,Fe, CO2)
self.pushButton_11.clicked.connect(self.buttonChart)
for row in range(self.tableWidget_3.rowCount()):
date_from = QtWidgets.QDateTimeEdit()
date_from.setDateTime(
QtCore.QDateTime(QtCore.QDate(2021, 8, 26),
QtCore.QTime(15, 0, 0))
)
self.tableWidget_3.setCellWidget(row, 0, date_from)
for row in range(self.tableWidget_3.rowCount()):
date_from = QDateTimeEdit()
date_from.setDateTime(
QDateTime(QDate(2021, 9, 2))
)
date_from.dateTimeChanged.connect(
lambda dateTime, row=row: self.date_changed(dateTime, row))
self.tableWidget_3.setCellWidget(row, 0, date_from)
self.dateTime0 = self.tableWidget_3.cellWidget(0, 0).dateTime()
# Расчет времени от начального значения
def date_changed(self, dateTime, row):
if row == 0:
self.dateTime0 = self.tableWidget_3.cellWidget(row, 0).dateTime()
for row in range(1, self.tableWidget_3.rowCount()):
dateTime2 = self.tableWidget_3.cellWidget(row, 0).dateTime()
item = QTableWidgetItem()
item.setData(Qt.DisplayRole,
self.dateTime0.secsTo(dateTime2) / 60. / 60.)
self.tableWidget_3.setItem(row, 1, item)
return
dateTime2 = self.tableWidget_3.cellWidget(row, 0).dateTime()
item = QTableWidgetItem()
item.setData(Qt.DisplayRole,
self.dateTime0.secsTo(dateTime2) / 60. / 60.)
self.tableWidget_3.setItem(row, 1, item)
# Кнопка дабовляющая строку в таблицу tableWidget_2
def buttonAdd(self):
rowPosition = self.tableWidget_2.rowCount()
self.tableWidget_2.insertRow(rowPosition)
# Кнопка удаляющая строку в таблицу tableWidget_2
def buttonDelete(self):
if self.tableWidget_2.rowCount() > 0:
self.tableWidget_2.removeRow(self.tableWidget_2.rowCount() - 1)
# Кнопка дабовляющая строку в таблицу tableWidget_3
def buttonAdd_2(self):
rowPosition = self.tableWidget_3.rowCount()
self.tableWidget_3.insertRow(rowPosition)
date_from = QtWidgets.QDateTimeEdit()
dateTime = QtCore.QDateTime().currentDateTime()
date_from.setDateTime(dateTime)
date_from.dateTimeChanged.connect(
lambda dateTime, row=rowPosition:
self.date_changed(dateTime, row))
self.tableWidget_3.setCellWidget(rowPosition, 0, date_from)
# Кнопка удаляющая строку в таблицу tableWidget_3
def buttonDelete_2(self):
if self.tableWidget_3.rowCount() > 0:
self.tableWidget_3.removeRow(self.tableWidget_3.rowCount() - 1)
# Сохранение данных из tableWidget_3
def buttonSave(self):
rows = self.tableWidget_3.rowCount()
cols = self.tableWidget_3.columnCount()
data_for_word = []
for row in range(rows):
tmp = []
for col in range(cols):
if col:
item = self.tableWidget_3.item(row, col)
if col == 1:
item = f'{float(item.text()):.0f}' if item else '0' # 0
else:
item = item.text() if item else '0' # 0
else:
item = self.tableWidget_3.cellWidget(row, 0). \
dateTime().toString('dd.MM.yyyy hh:mm')
tmp.append(item)
data_for_word.append(tmp)
for i in data_for_word: print(i)
self.buttonLoader(data_for_word)
# Загрузка данных в шаблон Word
def buttonLoader(self, data):
data_for_word = []
for item in data:
if any(item):
data_for_word.append({
"data": item[0],
"time": item[1],
"ph": item[2],
"ph2": item[3],
"fe": item[4],
"pm": item[5],
"co2": item[6],
"pm2": item[7],
"pm3": item[8]
})
print()
for i in data_for_word: print(i)
doc = DocxTemplate('test_word.docx')
context = {
'tbl_contents': data_for_word
}
doc.render(context)
doc.save('test2.docx')
def buttonChart(self, data):
data_for_word = []
rows = self.tableWidget_3.rowCount()
for row in range(rows):
dateTime = self.tableWidget_3.cellWidget(row, 0). \
dateTime().toString('dd.MM.yyyy hh:mm')
item = self.tableWidget_3.item(row, 1)
_data = item.data(Qt.DisplayRole) if item else '0'
data_for_word.append([dateTime, _data])
self.x, self.y = [], []
for x, y in data_for_word:
print(x, y)
# ??? datetime
self.x.append(datetime.strptime(x, '%d.%m.%Y %H:%M'))
self.y.append(float(y))
# ??? TimeAxisItem
self.date_axis = TimeAxisItem(orientation='bottom')
self.widget = pg.PlotWidget(
axisItems={'bottom': self.date_axis},
)
pen = pg.mkPen(color=(255, 0, 0), width=2)
self.widget.plot(
x=[x.timestamp() for x in self.x],
y=self.y, pen=pen, symbol='o'
)
self.gridLayout_3.addWidget(self.widget, 0, 0, 1, 1)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Widget()
ex.show()
sys.exit(app.exec_())
Код принимает данные из таблицы и выводит их в график, но график моем ui после нажатия на кнопку "Построить график" резко увеличивается.
Как это решить? (То есть как зафиксировать размер widget)
Код ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>498</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tab 1</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QTableWidget" name="tableWidget_3">
<row>
<property name="text">
<string>1</string>
</property>
</row>
<column>
<property name="text">
<string>1</string>
</property>
</column>
<column>
<property name="text">
<string>2</string>
</property>
</column>
<column>
<property name="text">
<string>3</string>
</property>
</column>
<column>
<property name="text">
<string>4</string>
</property>
</column>
<column>
<property name="text">
<string>5</string>
</property>
</column>
<column>
<property name="text">
<string>6</string>
</property>
</column>
<column>
<property name="text">
<string>7</string>
</property>
</column>
<column>
<property name="text">
<string>8</string>
</property>
</column>
<column>
<property name="text">
<string>9</string>
</property>
</column>
</widget>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout_21">
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>GroupBox</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="2" column="0">
<widget class="QPushButton" name="pushButton_11">
<property name="text">
<string>Просмотреть график</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="pushButton_9">
<property name="text">
<string>Добавить </string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButton_10">
<property name="text">
<string>Удалить</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget_2">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>График</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QWidget" name="widget" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Tab 2</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6"/>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Tab 2</string>
</attribute>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
Проблема:
Код ошибки:
Traceback (most recent call last):
File "G:\PyCharm\Gui_Программы\Python\Новая папка\SL_lke2.py", line 214, in buttonChart
w.deleteLater() # <----
AttributeError: 'NoneType' object has no attribute 'deleteLater'
Код ошибки 2:
Traceback (most recent call last):
File "G:\PyCharm\Gui_Программы\Python\Новая папка\GUI_Qt.py", line 194, in buttonChart
w.deleteLater() # <----
AttributeError: 'NoneType' object has no attribute 'deleteLater'
Ответы (1 шт):
Форма, которую вы предоставили в вопросе (Код ui) не соответствует форме, которую вы показываете на изображениях.
Вопрос: "Как зафиксировать размер
widget?"
Ответ:
void QWidget::
setFixedSize(intw, inth)Устанавливает ширину виджета
wи высотуh.
Установите строку например self.widget.setFixedSize(300, 300)
после строки self.gridLayout_3.addWidget(self.widget, 0, 0, 1, 1)
или какая там строка добавляет self.widget в Layout
...
self.gridLayout_3.addWidget(self.widget, 0, 0, 1, 1)
self.widget.setFixedSize(300, 300) # <----
...
Update
график сдвигается в левую сторону. Причем это не прошлый график сдвигается, а создается новый поверх старого.
...
# self.gridLayout_21.addWidget(self.widget, 0, 0, 1, 1)
w = self.findChild(PlotWidget, 'widget') # <----
print(f'w --> {w}')
w.deleteLater() # <----
self.gridLayout_3.addWidget(
self.widget,
0, 0, 1, 1,
alignment=Qt.AlignCenter # <----
)
self.widget.setFixedSize(500, 200) # <----
...
UPDATE 2
график сдвигается в левую сторону. Причем это не прошлый график сдвигается, а создается новый поверх старого.
я добавил пример ui может поможет, код выше не помог
@АндрейАлександров код выше - РАБОЧИЙ, для .ui, который вы предоставили первоначально.
Измененный .ui, который вы добавили - НЕ РАБОЧИЙ, в нем нет виджета PlotWidget.
Вот демонстрация того, что то что я писал выше работает, на вашем примере, который вы предоставили первоначально:
main.py
import sys
from datetime import datetime
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QWidget, QLabel
from PyQt5 import uic
from PyQt5.QtWidgets import QMainWindow
from PyQt5 import QtCore, QtWidgets
from PyQt5.Qt import *
from docxtpl import DocxTemplate
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg
class TimeAxisItem(pg.AxisItem):
def tickStrings(self, values, scale, spacing):
print(values, '\n', scale, '\n', spacing)
return [datetime.fromtimestamp(value) for value in values]
class Widget(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi("graph.ui", self)
# self.widget.setFixedSize(200, 400)
# Добавить/удалить строку в tableWidget_2
# self.pushButton_7.clicked.connect(self.buttonAdd)
# self.pushButton_8.clicked.connect(self.buttonDelete)
# Добавить/удалить строку в tableWidget_3
self.pushButton_9.clicked.connect(self.buttonAdd_2)
self.pushButton_10.clicked.connect(self.buttonDelete_2)
# Сохранить данные из таблицы tableWidget_3
# self.pushButton.clicked.connect(self.buttonSave)
# Создания графиков (Ph,Fe, CO2)
self.pushButton_11.clicked.connect(self.buttonChart)
for row in range(self.tableWidget_3.rowCount()):
date_from = QtWidgets.QDateTimeEdit()
date_from.setDateTime(
QtCore.QDateTime(QtCore.QDate(2021, 8, 26),
QtCore.QTime(15, 0, 0))
)
self.tableWidget_3.setCellWidget(row, 0, date_from)
for row in range(self.tableWidget_3.rowCount()):
date_from = QDateTimeEdit()
date_from.setDateTime(
QDateTime(QDate(2021, 9, 2))
)
date_from.dateTimeChanged.connect(
lambda dateTime, row=row: self.date_changed(dateTime, row))
self.tableWidget_3.setCellWidget(row, 0, date_from)
self.dateTime0 = self.tableWidget_3.cellWidget(0, 0).dateTime()
# Расчет времени от начального значения
def date_changed(self, dateTime, row):
if row == 0:
self.dateTime0 = self.tableWidget_3.cellWidget(row, 0).dateTime()
for row in range(1, self.tableWidget_3.rowCount()):
dateTime2 = self.tableWidget_3.cellWidget(row, 0).dateTime()
item = QTableWidgetItem()
item.setData(Qt.DisplayRole,
self.dateTime0.secsTo(dateTime2) / 60. / 60.)
self.tableWidget_3.setItem(row, 1, item)
return
dateTime2 = self.tableWidget_3.cellWidget(row, 0).dateTime()
item = QTableWidgetItem()
item.setData(Qt.DisplayRole,
self.dateTime0.secsTo(dateTime2) / 60. / 60.)
self.tableWidget_3.setItem(row, 1, item)
# Кнопка дабовляющая строку в таблицу tableWidget_2
def buttonAdd(self):
rowPosition = self.tableWidget_2.rowCount()
self.tableWidget_2.insertRow(rowPosition)
# Кнопка удаляющая строку в таблицу tableWidget_2
def buttonDelete(self):
if self.tableWidget_2.rowCount() > 0:
self.tableWidget_2.removeRow(self.tableWidget_2.rowCount() - 1)
# Кнопка дабовляющая строку в таблицу tableWidget_3
def buttonAdd_2(self):
rowPosition = self.tableWidget_3.rowCount()
self.tableWidget_3.insertRow(rowPosition)
date_from = QtWidgets.QDateTimeEdit()
dateTime = QtCore.QDateTime().currentDateTime()
date_from.setDateTime(dateTime)
date_from.dateTimeChanged.connect(
lambda dateTime, row=rowPosition:
self.date_changed(dateTime, row))
self.tableWidget_3.setCellWidget(rowPosition, 0, date_from)
# Кнопка удаляющая строку в таблицу tableWidget_3
def buttonDelete_2(self):
if self.tableWidget_3.rowCount() > 0:
self.tableWidget_3.removeRow(self.tableWidget_3.rowCount() - 1)
# Сохранение данных из tableWidget_3
def buttonSave(self):
rows = self.tableWidget_3.rowCount()
cols = self.tableWidget_3.columnCount()
data_for_word = []
for row in range(rows):
tmp = []
for col in range(cols):
if col:
item = self.tableWidget_3.item(row, col)
if col == 1:
item = f'{float(item.text()):.0f}' if item else '0' # 0
else:
item = item.text() if item else '0' # 0
else:
item = self.tableWidget_3.cellWidget(row, 0). \
dateTime().toString('dd.MM.yyyy hh:mm')
tmp.append(item)
data_for_word.append(tmp)
for i in data_for_word: print(i)
self.buttonLoader(data_for_word)
# Загрузка данных в шаблон Word
def buttonLoader(self, data):
data_for_word = []
for item in data:
if any(item):
data_for_word.append({
"data": item[0],
"time": item[1],
"ph": item[2],
"ph2": item[3],
"fe": item[4],
"pm": item[5],
"co2": item[6],
"pm2": item[7],
"pm3": item[8]
})
print()
for i in data_for_word: print(i)
doc = DocxTemplate('test_word.docx')
context = {
'tbl_contents': data_for_word
}
doc.render(context)
doc.save('test2.docx')
def buttonChart(self, data):
data_for_word = []
rows = self.tableWidget_3.rowCount()
for row in range(rows):
dateTime = self.tableWidget_3.cellWidget(row, 0). \
dateTime().toString('dd.MM.yyyy hh:mm')
item = self.tableWidget_3.item(row, 1)
_data = item.data(Qt.DisplayRole) if item else '0'
data_for_word.append([dateTime, _data])
self.x, self.y = [], []
for x, y in data_for_word:
print(x, y)
# ??? datetime
self.x.append(datetime.strptime(x, '%d.%m.%Y %H:%M'))
self.y.append(float(y))
# ??? TimeAxisItem
self.date_axis = TimeAxisItem(orientation='bottom')
self.widget = pg.PlotWidget(
axisItems={'bottom': self.date_axis},
)
pen = pg.mkPen(color=(255, 0, 0), width=2)
self.widget.plot(
x=[x.timestamp() for x in self.x],
y=self.y, pen=pen, symbol='o'
)
# self.gridLayout_21.addWidget(self.widget, 0, 0, 1, 1)
w = self.findChild(PlotWidget, 'widget') # <----
print(f'w --> {w}')
w.deleteLater() # <----
self.gridLayout_3.addWidget(
self.widget,
0, 0, 1, 1,
alignment=Qt.AlignCenter # <----
)
self.widget.setFixedSize(500, 200) # <----
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Widget()
ex.show()
sys.exit(app.exec_())
graph.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Таблица</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QTableWidget" name="tableWidget_3">
<row>
<property name="text">
<string>1</string>
</property>
</row>
<column>
<property name="text">
<string>1</string>
</property>
</column>
<column>
<property name="text">
<string>2</string>
</property>
</column>
<column>
<property name="text">
<string>3</string>
</property>
</column>
<column>
<property name="text">
<string>4</string>
</property>
</column>
<column>
<property name="text">
<string>5</string>
</property>
</column>
<column>
<property name="text">
<string>6</string>
</property>
</column>
<column>
<property name="text">
<string>7</string>
</property>
</column>
<column>
<property name="text">
<string>8</string>
</property>
</column>
<column>
<property name="text">
<string>9</string>
</property>
</column>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Считать данные</string>
</property>
</widget>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton_10">
<property name="text">
<string>Удалить</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_9">
<property name="text">
<string>Добавить</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButton_11">
<property name="text">
<string>Создать график</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>График</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="PlotWidget" name="widget" native="true"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
<customwidget>
<class>PlotWidget</class>
<extends>QWidget</extends>
<header>pyqtgraph</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>




