Как добавлять и удалять строки в QTableWidget?
Есть код, в котором вставляется в первый столбец таблицы tableWidget_3 данные dataEdit.
Как сделать так чтобы по нажатию на кнопку "удалить строку" строка удалялась,
а по нажатию на "добавить" - строку добавлялась?
main.py
import sys
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 *
class Widget(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi("UI_lke2.ui", self)
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)
def buttonLoader(self):
pass
data_for_word = []
rows = self.tableWidget_3.rowCount()
cols = self.tableWidget_3.columnCount()
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)
data_for_word.append([dateTime, _data])
print(f'\n{data_for_word}\n')
print(*data_for_word, sep='\n')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Widget()
ex.show()
sys.exit(app.exec_())
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Я отметил для вас блок и строки, которые надо изменить.
Обратите внимание UI_lke2.ui, в нем не должно быть строк в таблице!
Таблица в Qt Designer содержит только столбцы!
Строки добавляем через insertRow.
void QTableWidget::
insertRow(int row)Вставляет пустую строку в таблицу в строке (int row).
main.py
import sys
from PyQt5 import QtCore, QtWidgets, QtGui, uic
from PyQt5.Qt import *
class Widget(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi("UI_lke2.ui", self) # !!! UI_lke2.ui изменен !!!
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
self.tableWidget_3.horizontalHeader().setSectionResizeMode(
QtWidgets.QHeaderView.Stretch)
self.btn_add = QtWidgets.QPushButton('Add')
self.btn_add.clicked.connect(self.add_row)
self.btn_delete = QtWidgets.QPushButton("Delete")
self.btn_delete.clicked.connect(self.delete_row)
self.gridLayout.addWidget(self.tableWidget_3, 0, 0, 1, 2)
self.gridLayout.addWidget(self.btn_add, 1, 0, 1, 1)
self.gridLayout.addWidget(self.btn_delete, 1, 1, 1, 1)
for _ in range(3):
rowPosition = self.tableWidget_3.rowCount()
self.tableWidget_3.insertRow(rowPosition) # !!! insertRow
date_from = QtWidgets.QDateTimeEdit()
dateTime = QtCore.QDateTime().currentDateTime()
date_from.setDateTime(QtCore.QDateTime(
QtCore.QDate(2021, 8, 26), QtCore.QTime(15, 0, 0)
)
)
date_from.dateTimeChanged.connect(
lambda dateTime, row=rowPosition:
self.date_changed(dateTime, row))
self.tableWidget_3.setCellWidget(rowPosition, 0, date_from)
self.dateTime0 = self.tableWidget_3.cellWidget(0, 0).dateTime()
self.date_changed(self.dateTime0, 0)
self.btn_add.setFocus()
def add_row(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)
self.date_changed(dateTime, rowPosition)
def delete_row(self):
row = self.tableWidget_3.currentRow()
if row == 0:
QMessageBox.warning(
self,
"ВНИМАНИЕ",
"<b style='color: red;'>НЕ НАДО УДАЛЯТЬ ПЕРВУЮ СТРОКУ!</b>"
)
return
elif row == -1:
msg = QMessageBox.question(
self,
'Message',
"Выберите строку, которую вы хотите удалить.",
QMessageBox.Ok
)
return
else:
msg = QMessageBox.question(
self,
"Внимание подтвердите удаление строки!",
"Вы действительно хотите удалить "
f"строку <b style='color: red;'>{row+1}</b> ?",
QMessageBox.Ok | QMessageBox.Cancel
)
if msg == QtWidgets.QMessageBox.Cancel:
return
for _row in range(self.tableWidget_3.rowCount()):
date_from = self.tableWidget_3.cellWidget(_row, 0)
date_from.dateTimeChanged.disconnect()
self.tableWidget_3.removeRow(row)
for _row in range(self.tableWidget_3.rowCount()):
date_from = self.tableWidget_3.cellWidget(_row, 0)
date_from.dateTimeChanged.connect(
lambda dateTime, row=_row:
self.date_changed(dateTime, row))
self.btn_add.setFocus()
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
def date_changed(self, dateTime, row):
if not self.tableWidget_3.cellWidget(row, 0): # +++
return # +++
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)
def buttonLoader(self):
pass
data_for_word = []
rows = self.tableWidget_3.rowCount()
cols = self.tableWidget_3.columnCount()
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)
data_for_word.append([dateTime, _data])
print(f'\n{data_for_word}\n')
print(*data_for_word, sep='\n')
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold))
ex = Widget()
ex.resize(500, 400)
ex.show()
sys.exit(app.exec_())
UI_lke2.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>320</width>
<height>240</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="QTableWidget" name="tableWidget_3">
<column>
<property name="text">
<string>1</string>
</property>
</column>
<column>
<property name="text">
<string>2</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>320</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>


