Reputation: 155
My list widget placed inside a window prints out values (0 - 1000) when button1 is pressed. But some of these values are 0's and signify an error. The user is expected to update these values with any other positive integer. Once the value is confirmed by pressing a button2, the list will be updated or an error is shown that it needs to be further updated.
The following is my code.
import Ui_ImageSort # designed using Qt-Designer
from PyQt5 import QtCore
from PyQt5.QtWidgets import QMainWindow, QListWidgetItem
class ImageSort(Ui_ImageSort.Ui_MainWindow, QMainWindow):
def __init__(self):
super(ImageSort, self).__init__()
self.setupUi(self)
self.pushButton_1.clicked.connect(list_view)
self.pushButton_2.clicked.connect(print_scales)
def list_view(self):
self.listWidget.clear()
for i in range(len(self.scale_txt)):
item = QListWidgetItem(str(self.scale_txt[i]))
self.listWidget.addItem(str(i + 1) + ") " + item.text())
def print_scales(self):
self.listWidget.clear()
error = 0
for i in range(len(self.scale_txt)):
if (self.scale_txt[i]==0):
error = 1
if (error ==0):
self.listWidget.addItem("\nThe scale values are confirmed ")
for i in range(len(self.scale_txt)):
print(self.scale_txt[i])
print("\n")
else:
self.listWidget.addItem("\nThe scale values have an error")
self.listWidget.addItem("Press button 1 again to edit")
I would like to edit only the digits the the listwidget prints out. The output will look something like this:
1) 100 microns
2) 200 microns
3) 0 microns
4) 100 microns
The value 0 needs to be corrected. So it should be marked red. And the user can change without affecting the remaining line ("microns"). For example: "0 microns" is invalid, marked in red and should be editable, but after the user replaces it with some other digits, presses button2, then it becomes valid and is, therefore, turned black and is no longer editable.
Upvotes: 0
Views: 710
Reputation: 243897
One possible solution is to use a delegate, and the data is passed through the roles:
from PyQt5 import QtCore, QtGui, QtWidgets
MaskRole = QtCore.Qt.UserRole + 1000
class ListDelegate(QtWidgets.QStyledItemDelegate):
def createEditor(self, parent, option, index):
mask = index.data(MaskRole)
if mask is not None:
editor = QtWidgets.QLineEdit(parent)
editor.setInputMask(mask)
return editor
def setModelData(self, editor, model, index):
if editor.hasAcceptableInput():
text = editor.text()
model.setData(index, text, QtCore.Qt.DisplayRole)
re = QtCore.QRegularExpression(r"(\d+)\) (\d+) microns")
match = re.match(index.data())
color = QtGui.QColor("red")
if match.hasMatch():
val = match.captured(match.lastCapturedIndex())
if val != "0":
color = QtGui.QColor("black")
model.setData(index, color, QtCore.Qt.ForegroundRole)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = QtWidgets.QListWidget()
delegate = ListDelegate(w)
w.setItemDelegate(delegate)
scales = [100, 200, 0, 500, 0, 300, 0]
for i, scale in enumerate(scales):
item = QtWidgets.QListWidgetItem()
if scale == 0:
item.setData(MaskRole, "{}) 900 micro\\ns".format(i))
item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
item.setForeground(QtCore.Qt.red)
item.setText("{}) {} microns".format(i, scale))
w.addItem(item)
w.show()
sys.exit(app.exec_())
Upvotes: 1