I am writing up a GUI with a editfield in PyQt5 using QCompleter to allow the user to select the input from a pop up list. The list is built into a QStandardItem and provided to QCompleter. What I need is the index to the row in QStandardItem model, when the user has selected an item from the pop up list.
I have tried to study the doc https://doc.qt.io/qt-5/qcompleter.html and found a section called
Iterating Through Completions To retrieve a single candidate string, call setCompletionPrefix() with the text that needs to be completed and call currentCompletion().
This is not useful in my case, because there is a risk that duplicated item exists in my QStandardItem model, e.g. ['cat,'cat','dog']. Depending if user select first or second cat, there are two different Ids associated with it. Therefore, it is important to get the index of QStandardItem model for the item that user has selected.
self.model = QtGui.QStandardItemModel()
#Merge the lists Id, IdCompound, self.SCL_Name together using zip. Id, IdCompount are int, while self.SCL_Name is str
ziplist1 = list(zip(Id, IdCompound, self.SCL_Name))
ziplist2 = list(zip(Id, IdCompound, self.SCL_OtherNames))
#Append the fields in ziplist1 and ziplist2 into
for name in ziplist1:
row = list()
for col in name:
cell = QtGui.QStandardItem(col) #Has made sure that everything is a string
row.append(cell)
self.model.appendRow(row)
for name in ziplist2:
row = list()
for col in name:
cell = QtGui.QStandardItem(col)
row.append(cell)
self.model.appendRow(row)
self.completer = QtWidgets.QCompleter()
self.completer.setModel(self.model)
self.completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.completer.activated.connect(self.complete_excipient_input)
self.completer.setCompletionColumn(2)
what should I do in self.completer.activated.connect(self.complete_excipient_input) in order to get index in the self.model corresponding to the user selected item?
Edit
I have tried to run the code example provided by @eyllanesc and it works fine. However, when I apply the code into my own code, I get error message stating QObject::connect: Cannot connect QCompleter::activated(QModelIndex) to
(null)::onActivated(QModelIndex)
and Exception has occurred: TypeError connect() failed between activated(QModelIndex) and onActivated()
Below is my code. It is generated in QtDesigner and subsequently converted to python code.
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'main_v01.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
import EBM_DB_tools as tool
class Ui_mainWindow(object):
def setupUi(self, mainWindow):
mainWindow.setObjectName("mainWindow")
mainWindow.resize(1195, 818)
mainWindow.setWindowOpacity(2.0)
mainWindow.setAutoFillBackground(False)
mainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonFollowStyle)
self.centralwidget = QtWidgets.QWidget(mainWindow)
self.centralwidget.setObjectName("centralwidget")
self.lineedit_api = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_api.setGeometry(QtCore.QRect(30, 130, 143, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.lineedit_api.setFont(font)
self.lineedit_api.setObjectName("lineedit_api")
self.pb_apiinsert = QtWidgets.QPushButton(self.centralwidget)
self.pb_apiinsert.setGeometry(QtCore.QRect(630, 130, 75, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.pb_apiinsert.setFont(font)
self.pb_apiinsert.setAutoFillBackground(False)
self.pb_apiinsert.setObjectName("pb_apiinsert")
self.api_amount = QtWidgets.QLineEdit(self.centralwidget)
self.api_amount.setGeometry(QtCore.QRect(178, 130, 142, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.api_amount.setFont(font)
self.api_amount.setObjectName("api_amount")
self.ItemTable = QtWidgets.QTableView(self.centralwidget)
self.ItemTable.setGeometry(QtCore.QRect(30, 270, 471, 281))
self.ItemTable.setObjectName("ItemTable")
self.dropdown_apiunit = QtWidgets.QComboBox(self.centralwidget)
self.dropdown_apiunit.setGeometry(QtCore.QRect(330, 130, 80, 26))
self.dropdown_apiunit.setObjectName("dropdown_apiunit")
self.dropdown_apiunit.addItem("")
self.dropdown_apiunit.addItem("")
self.dropdown_apiunit.addItem("")
self.dropdown_apiunit.addItem("")
self.pb_BatchRegisterLabel = QtWidgets.QPushButton(self.centralwidget)
self.pb_BatchRegisterLabel.setGeometry(QtCore.QRect(280, 570, 221, 111))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.pb_BatchRegisterLabel.setFont(font)
self.pb_BatchRegisterLabel.setObjectName("pb_BatchRegisterLabel")
self.pb_removeTableEntry = QtWidgets.QPushButton(self.centralwidget)
self.pb_removeTableEntry.setGeometry(QtCore.QRect(520, 390, 75, 23))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.pb_removeTableEntry.setFont(font)
self.pb_removeTableEntry.setObjectName("pb_removeTableEntry")
self.lineedit_projectno = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_projectno.setGeometry(QtCore.QRect(620, 50, 91, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.lineedit_projectno.setFont(font)
self.lineedit_projectno.setText("")
self.lineedit_projectno.setObjectName("lineedit_projectno")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(720, 50, 21, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(26)
self.label.setFont(font)
self.label.setObjectName("label")
self.lineedit_formulationno = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_formulationno.setGeometry(QtCore.QRect(740, 50, 91, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.lineedit_formulationno.setFont(font)
self.lineedit_formulationno.setText("")
self.lineedit_formulationno.setObjectName("lineedit_formulationno")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(840, 50, 21, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(26)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.lineedit_apino = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_apino.setGeometry(QtCore.QRect(860, 50, 91, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.lineedit_apino.setFont(font)
self.lineedit_apino.setText("")
self.lineedit_apino.setObjectName("lineedit_apino")
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setGeometry(QtCore.QRect(960, 50, 21, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(26)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.lineedit_batchno = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_batchno.setGeometry(QtCore.QRect(980, 50, 71, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.lineedit_batchno.setFont(font)
self.lineedit_batchno.setText("")
self.lineedit_batchno.setObjectName("lineedit_batchno")
self.dropdown_processtype = QtWidgets.QComboBox(self.centralwidget)
self.dropdown_processtype.setGeometry(QtCore.QRect(30, 50, 291, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.dropdown_processtype.setFont(font)
self.dropdown_processtype.setObjectName("dropdown_processtype")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.setItemText(0, "")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setGeometry(QtCore.QRect(30, 20, 141, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.label_4.setFont(font)
self.label_4.setObjectName("label_4")
self.textEdit_comment = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit_comment.setGeometry(QtCore.QRect(630, 300, 511, 251))
self.textEdit_comment.setObjectName("textEdit_comment")
self.label_5 = QtWidgets.QLabel(self.centralwidget)
self.label_5.setGeometry(QtCore.QRect(630, 260, 151, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.label_5.setFont(font)
self.label_5.setObjectName("label_5")
self.label_6 = QtWidgets.QLabel(self.centralwidget)
self.label_6.setGeometry(QtCore.QRect(620, 20, 151, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.label_6.setFont(font)
self.label_6.setObjectName("label_6")
self.PushButton_NNCnoImport = QtWidgets.QPushButton(self.centralwidget)
self.PushButton_NNCnoImport.setGeometry(QtCore.QRect(1070, 30, 91, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.PushButton_NNCnoImport.setFont(font)
self.PushButton_NNCnoImport.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.PushButton_NNCnoImport.setObjectName("PushButton_NNCnoImport")
self.pb_formulationRegister = QtWidgets.QPushButton(self.centralwidget)
self.pb_formulationRegister.setGeometry(QtCore.QRect(30, 570, 221, 111))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.pb_formulationRegister.setFont(font)
self.pb_formulationRegister.setObjectName("pb_formulationRegister")
self.TextEdit_api = QtWidgets.QTextEdit(self.centralwidget)
self.TextEdit_api.setGeometry(QtCore.QRect(420, 130, 191, 26))
self.TextEdit_api.setObjectName("TextEdit_api")
self.TextEdit_Excipient = QtWidgets.QTextEdit(self.centralwidget)
self.TextEdit_Excipient.setGeometry(QtCore.QRect(420, 170, 191, 26))
self.TextEdit_Excipient.setObjectName("TextEdit_Excipient")
self.PushButton_Scan = QtWidgets.QPushButton(self.centralwidget)
self.PushButton_Scan.setGeometry(QtCore.QRect(1070, 60, 91, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.PushButton_Scan.setFont(font)
self.PushButton_Scan.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.PushButton_Scan.setObjectName("PushButton_Scan")
self.label_7 = QtWidgets.QLabel(self.centralwidget)
self.label_7.setGeometry(QtCore.QRect(420, 100, 141, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.label_7.setFont(font)
self.label_7.setObjectName("label_7")
self.lineedit_ExcipientName = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_ExcipientName.setGeometry(QtCore.QRect(30, 170, 143, 26))
self.lineedit_ExcipientName.setCompleter(self.completer)
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.lineedit_ExcipientName.setFont(font)
self.lineedit_ExcipientName.setObjectName("lineedit_ExcipientName")
self.lineedit_excipientamount = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_excipientamount.setGeometry(QtCore.QRect(180, 170, 142, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.lineedit_excipientamount.setFont(font)
self.lineedit_excipientamount.setObjectName("lineedit_excipientamount")
self.dropdown_excipientunit = QtWidgets.QComboBox(self.centralwidget)
self.dropdown_excipientunit.setGeometry(QtCore.QRect(330, 170, 80, 26))
self.dropdown_excipientunit.setObjectName("dropdown_excipientunit")
self.dropdown_excipientunit.addItem("")
self.dropdown_excipientunit.addItem("")
self.dropdown_excipientunit.addItem("")
self.dropdown_excipientunit.addItem("")
self.pb_excipientinsert = QtWidgets.QPushButton(self.centralwidget)
self.pb_excipientinsert.setGeometry(QtCore.QRect(630, 170, 75, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.pb_excipientinsert.setFont(font)
self.pb_excipientinsert.setObjectName("pb_excipientinsert")
mainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(mainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1195, 21))
self.menubar.setObjectName("menubar")
mainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(mainWindow)
self.statusbar.setObjectName("statusbar")
mainWindow.setStatusBar(self.statusbar)
self.retranslateUi(mainWindow)
QtCore.QMetaObject.connectSlotsByName(mainWindow)
mainWindow.setTabOrder(self.lineedit_api, self.api_amount)
mainWindow.setTabOrder(self.api_amount, self.dropdown_apiunit)
mainWindow.setTabOrder(self.dropdown_apiunit, self.pb_apiinsert)
mainWindow.setTabOrder(self.pb_apiinsert, self.lineedit_ExcipientName)
mainWindow.setTabOrder(self.lineedit_ExcipientName, self.lineedit_excipientamount)
mainWindow.setTabOrder(self.lineedit_excipientamount, self.dropdown_excipientunit)
mainWindow.setTabOrder(self.dropdown_excipientunit, self.pb_excipientinsert)
mainWindow.setTabOrder(self.pb_excipientinsert, self.ItemTable)
mainWindow.setTabOrder(self.ItemTable, self.textEdit_comment)
mainWindow.setTabOrder(self.textEdit_comment, self.pb_BatchRegisterLabel)
mainWindow.setTabOrder(self.pb_BatchRegisterLabel, self.lineedit_projectno)
mainWindow.setTabOrder(self.lineedit_projectno, self.lineedit_formulationno)
mainWindow.setTabOrder(self.lineedit_formulationno, self.lineedit_apino)
mainWindow.setTabOrder(self.lineedit_apino, self.lineedit_batchno)
mainWindow.setTabOrder(self.lineedit_batchno, self.dropdown_processtype)
mainWindow.setTabOrder(self.dropdown_processtype, self.pb_removeTableEntry)
def retranslateUi(self, mainWindow):
_translate = QtCore.QCoreApplication.translate
mainWindow.setWindowTitle(_translate("mainWindow", "MainWindow"))
self.lineedit_api.setText(_translate("mainWindow", "API NNCNo"))
self.pb_apiinsert.setText(_translate("mainWindow", "Insert"))
self.api_amount.setText(_translate("mainWindow", "Amount"))
self.dropdown_apiunit.setItemText(0, _translate("mainWindow", "mg"))
self.dropdown_apiunit.setItemText(1, _translate("mainWindow", "mg/tablet"))
self.dropdown_apiunit.setItemText(2, _translate("mainWindow", "% (w/w)"))
self.dropdown_apiunit.setItemText(3, _translate("mainWindow", "mg/capsule"))
self.pb_BatchRegisterLabel.setText(_translate("mainWindow", "Batch Register and Label"))
self.pb_removeTableEntry.setText(_translate("mainWindow", "Remove"))
self.label.setText(_translate("mainWindow", "-"))
self.label_2.setText(_translate("mainWindow", "-"))
self.label_3.setText(_translate("mainWindow", "-"))
self.dropdown_processtype.setItemText(1, _translate("mainWindow", "option 1"))
self.dropdown_processtype.setItemText(2, _translate("mainWindow", "option 2"))
self.dropdown_processtype.setItemText(3, _translate("mainWindow", "option 3"))
self.dropdown_processtype.setItemText(4, _translate("mainWindow", "option 4"))
self.dropdown_processtype.setItemText(5, _translate("mainWindow", "option 5"))
self.dropdown_processtype.setItemText(6, _translate("mainWindow", "option 6"))
self.dropdown_processtype.setItemText(7, _translate("mainWindow", "option 7"))
self.dropdown_processtype.setItemText(8, _translate("mainWindow", "User specify"))
self.label_4.setText(_translate("mainWindow", "Process Type"))
self.textEdit_comment.setHtml(_translate("mainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.label_5.setText(_translate("mainWindow", "Comment"))
self.label_6.setText(_translate("mainWindow", "NNC No"))
self.PushButton_NNCnoImport.setText(_translate("mainWindow", "Import"))
self.pb_formulationRegister.setText(_translate("mainWindow", "Register Formulation"))
self.TextEdit_api.setHtml(_translate("mainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.TextEdit_Excipient.setHtml(_translate("mainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.PushButton_Scan.setText(_translate("mainWindow", "Scan"))
self.label_7.setText(_translate("mainWindow", "Comments"))
self.lineedit_ExcipientName.setText(_translate("mainWindow", "Excipient Name"))
self.lineedit_excipientamount.setText(_translate("mainWindow", "Amount"))
self.dropdown_excipientunit.setItemText(0, _translate("mainWindow", "mg"))
self.dropdown_excipientunit.setItemText(1, _translate("mainWindow", "mg/tablet"))
self.dropdown_excipientunit.setItemText(2, _translate("mainWindow", "% (w/w)"))
self.dropdown_excipientunit.setItemText(3, _translate("mainWindow", "mg/capsule"))
self.pb_excipientinsert.setText(_translate("mainWindow", "Insert"))
def __init__(self):
#upon initiation store the path to the different REST calls
self.url_standardcomponent = "http://somewhere"
#self.url_auth = " http://somwhere"
#self.username = 'username'
#self.password = 'password' #This must be changed later using Keberos-requests
#Import the standard component
tool.import_standardcomponent(self)
#Prepare the model for completer
self.model = QtGui.QStandardItemModel()
#The StandardModelItem only accepts string and not int, therefore a conversion is required
Id = [str(thing) for thing in self.SCL_Id]
IdCompound = [str(thing) for thing in self.SCL_IdCompound]
ziplist1 = list(zip(Id, IdCompound, self.SCL_Name))
ziplist2 = list(zip(Id, IdCompound, self.SCL_OtherNames))
#The idea here is to create a list with 3 columns. The 1., 2. columns being Id and IdCompounds. The 3rd comlumn is contains Name.
#Once done, the list will be append with OtherNames in the 3rd column. Reason being QCompleter can only match one column. Therefore
#Name and OtherNames have to be in 3rd column
for name in ziplist1:
row = list()
for col in name:
cell = QtGui.QStandardItem(col) #Has made sure that everything is a string
row.append(cell)
self.model.appendRow(row)
for name in ziplist2:
row = list()
for col in name:
cell = QtGui.QStandardItem(col)
row.append(cell)
self.model.appendRow(row)
#Prepare the completer
self.completer = QtWidgets.QCompleter()
self.completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.completer.setCompletionColumn(2) #Will use 2nd column containing both Name and OtherNames for completion
self.completer.setModel(self.model)
#I get the described error when running the below line. Also I have a question, does bracket [QtCore.QMOdelIndex] mean that the class is provided as a list?
self.completer.activated[QtCore.QModelIndex].connect(self.onActivated)
@QtCore.pyqtSlot(QtCore.QModelIndex)
def onActivated(self, index):
_id = index.sibling(index.row(), 0).data()
_id_compound = index.sibling(index.row(), 1).data()
text = index.data()
print(_id, _id_compound, text)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
mainWindow = QtWidgets.QMainWindow()
ui = Ui_mainWindow()
ui.setupUi(mainWindow)
mainWindow.show()
sys.exit(app.exec_())
The activated signal is overloaded, that is, it can return QString
(by default, in python str
) or a QModelIndex
. So it must be indicated by using completer.activated [QtCore.QModelIndex].connect(...)
, obtaining the QModelIndex you can get siblings using the sibling method, or the items using the itemFromIndex() method.
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
Id = ["1", "2", "3", "4", "5", "6"]
IdCompound = ["a", "b", "c", "d", "e", "f"]
SCL_Name = ["p", "p", "q", "q", "r", "r"]
SCL_OtherNames = ["x", "x", "y", "y", "z", "z"]
ziplist1 = list(zip(Id, IdCompound, SCL_Name))
ziplist2 = list(zip(Id, IdCompound, SCL_OtherNames))
self.m_model = QtGui.QStandardItemModel()
for name in ziplist1 + ziplist2:
row = list()
for col in name:
cell = QtGui.QStandardItem(col)
row.append(cell)
self.m_model.appendRow(row)
self.m_completer = QtWidgets.QCompleter(
completionColumn=2, caseSensitivity=QtCore.Qt.CaseInsensitive
)
self.m_completer.setModel(self.m_model)
self.m_completer.activated[QtCore.QModelIndex].connect(self.onActivated)
self.m_lineedit = QtWidgets.QLineEdit()
self.m_lineedit.setCompleter(self.m_completer)
self.m_tableview = QtWidgets.QTableView()
self.m_tableview.setModel(self.m_model)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.m_lineedit)
lay.addWidget(self.m_tableview)
@QtCore.pyqtSlot(QtCore.QModelIndex)
def onActivated(self, index):
_id = index.sibling(index.row(), 0).data()
_id_compound = index.sibling(index.row(), 1).data()
text = index.data()
print(_id, _id_compound, text)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
sc = Widget()
sc.show()
sys.exit(app.exec_())
You should not modify the class generated by Qt Designer(1) since it is not a widget, instead you should create another class that inherits the appropriate widget(2) and use the initial class to fill it. The decorator @pyqtSlot() only works in QObject like the widgets, in your case Ui_MainWindow is not, therefore you observe that error.
Considering that the solution is:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'main_v01.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
# import EBM_DB_tools as tool
class Ui_mainWindow(object):
def setupUi(self, mainWindow):
mainWindow.setObjectName("mainWindow")
mainWindow.resize(1195, 818)
mainWindow.setWindowOpacity(2.0)
mainWindow.setAutoFillBackground(False)
mainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonFollowStyle)
self.centralwidget = QtWidgets.QWidget(mainWindow)
self.centralwidget.setObjectName("centralwidget")
self.lineedit_api = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_api.setGeometry(QtCore.QRect(30, 130, 143, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.lineedit_api.setFont(font)
self.lineedit_api.setObjectName("lineedit_api")
self.pb_apiinsert = QtWidgets.QPushButton(self.centralwidget)
self.pb_apiinsert.setGeometry(QtCore.QRect(630, 130, 75, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.pb_apiinsert.setFont(font)
self.pb_apiinsert.setAutoFillBackground(False)
self.pb_apiinsert.setObjectName("pb_apiinsert")
self.api_amount = QtWidgets.QLineEdit(self.centralwidget)
self.api_amount.setGeometry(QtCore.QRect(178, 130, 142, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.api_amount.setFont(font)
self.api_amount.setObjectName("api_amount")
self.ItemTable = QtWidgets.QTableView(self.centralwidget)
self.ItemTable.setGeometry(QtCore.QRect(30, 270, 471, 281))
self.ItemTable.setObjectName("ItemTable")
self.dropdown_apiunit = QtWidgets.QComboBox(self.centralwidget)
self.dropdown_apiunit.setGeometry(QtCore.QRect(330, 130, 80, 26))
self.dropdown_apiunit.setObjectName("dropdown_apiunit")
self.dropdown_apiunit.addItem("")
self.dropdown_apiunit.addItem("")
self.dropdown_apiunit.addItem("")
self.dropdown_apiunit.addItem("")
self.pb_BatchRegisterLabel = QtWidgets.QPushButton(self.centralwidget)
self.pb_BatchRegisterLabel.setGeometry(QtCore.QRect(280, 570, 221, 111))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.pb_BatchRegisterLabel.setFont(font)
self.pb_BatchRegisterLabel.setObjectName("pb_BatchRegisterLabel")
self.pb_removeTableEntry = QtWidgets.QPushButton(self.centralwidget)
self.pb_removeTableEntry.setGeometry(QtCore.QRect(520, 390, 75, 23))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.pb_removeTableEntry.setFont(font)
self.pb_removeTableEntry.setObjectName("pb_removeTableEntry")
self.lineedit_projectno = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_projectno.setGeometry(QtCore.QRect(620, 50, 91, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.lineedit_projectno.setFont(font)
self.lineedit_projectno.setText("")
self.lineedit_projectno.setObjectName("lineedit_projectno")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(720, 50, 21, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(26)
self.label.setFont(font)
self.label.setObjectName("label")
self.lineedit_formulationno = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_formulationno.setGeometry(QtCore.QRect(740, 50, 91, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.lineedit_formulationno.setFont(font)
self.lineedit_formulationno.setText("")
self.lineedit_formulationno.setObjectName("lineedit_formulationno")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(840, 50, 21, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(26)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.lineedit_apino = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_apino.setGeometry(QtCore.QRect(860, 50, 91, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.lineedit_apino.setFont(font)
self.lineedit_apino.setText("")
self.lineedit_apino.setObjectName("lineedit_apino")
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setGeometry(QtCore.QRect(960, 50, 21, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(26)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.lineedit_batchno = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_batchno.setGeometry(QtCore.QRect(980, 50, 71, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.lineedit_batchno.setFont(font)
self.lineedit_batchno.setText("")
self.lineedit_batchno.setObjectName("lineedit_batchno")
self.dropdown_processtype = QtWidgets.QComboBox(self.centralwidget)
self.dropdown_processtype.setGeometry(QtCore.QRect(30, 50, 291, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.dropdown_processtype.setFont(font)
self.dropdown_processtype.setObjectName("dropdown_processtype")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.setItemText(0, "")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.dropdown_processtype.addItem("")
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setGeometry(QtCore.QRect(30, 20, 141, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.label_4.setFont(font)
self.label_4.setObjectName("label_4")
self.textEdit_comment = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit_comment.setGeometry(QtCore.QRect(630, 300, 511, 251))
self.textEdit_comment.setObjectName("textEdit_comment")
self.label_5 = QtWidgets.QLabel(self.centralwidget)
self.label_5.setGeometry(QtCore.QRect(630, 260, 151, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.label_5.setFont(font)
self.label_5.setObjectName("label_5")
self.label_6 = QtWidgets.QLabel(self.centralwidget)
self.label_6.setGeometry(QtCore.QRect(620, 20, 151, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.label_6.setFont(font)
self.label_6.setObjectName("label_6")
self.PushButton_NNCnoImport = QtWidgets.QPushButton(self.centralwidget)
self.PushButton_NNCnoImport.setGeometry(QtCore.QRect(1070, 30, 91, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.PushButton_NNCnoImport.setFont(font)
self.PushButton_NNCnoImport.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.PushButton_NNCnoImport.setObjectName("PushButton_NNCnoImport")
self.pb_formulationRegister = QtWidgets.QPushButton(self.centralwidget)
self.pb_formulationRegister.setGeometry(QtCore.QRect(30, 570, 221, 111))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.pb_formulationRegister.setFont(font)
self.pb_formulationRegister.setObjectName("pb_formulationRegister")
self.TextEdit_api = QtWidgets.QTextEdit(self.centralwidget)
self.TextEdit_api.setGeometry(QtCore.QRect(420, 130, 191, 26))
self.TextEdit_api.setObjectName("TextEdit_api")
self.TextEdit_Excipient = QtWidgets.QTextEdit(self.centralwidget)
self.TextEdit_Excipient.setGeometry(QtCore.QRect(420, 170, 191, 26))
self.TextEdit_Excipient.setObjectName("TextEdit_Excipient")
self.PushButton_Scan = QtWidgets.QPushButton(self.centralwidget)
self.PushButton_Scan.setGeometry(QtCore.QRect(1070, 60, 91, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.PushButton_Scan.setFont(font)
self.PushButton_Scan.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.PushButton_Scan.setObjectName("PushButton_Scan")
self.label_7 = QtWidgets.QLabel(self.centralwidget)
self.label_7.setGeometry(QtCore.QRect(420, 100, 141, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.label_7.setFont(font)
self.label_7.setObjectName("label_7")
self.lineedit_ExcipientName = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_ExcipientName.setGeometry(QtCore.QRect(30, 170, 143, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.lineedit_ExcipientName.setFont(font)
self.lineedit_ExcipientName.setObjectName("lineedit_ExcipientName")
self.lineedit_excipientamount = QtWidgets.QLineEdit(self.centralwidget)
self.lineedit_excipientamount.setGeometry(QtCore.QRect(180, 170, 142, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.lineedit_excipientamount.setFont(font)
self.lineedit_excipientamount.setObjectName("lineedit_excipientamount")
self.dropdown_excipientunit = QtWidgets.QComboBox(self.centralwidget)
self.dropdown_excipientunit.setGeometry(QtCore.QRect(330, 170, 80, 26))
self.dropdown_excipientunit.setObjectName("dropdown_excipientunit")
self.dropdown_excipientunit.addItem("")
self.dropdown_excipientunit.addItem("")
self.dropdown_excipientunit.addItem("")
self.dropdown_excipientunit.addItem("")
self.pb_excipientinsert = QtWidgets.QPushButton(self.centralwidget)
self.pb_excipientinsert.setGeometry(QtCore.QRect(630, 170, 75, 26))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.pb_excipientinsert.setFont(font)
self.pb_excipientinsert.setObjectName("pb_excipientinsert")
mainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(mainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1195, 21))
self.menubar.setObjectName("menubar")
mainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(mainWindow)
self.statusbar.setObjectName("statusbar")
mainWindow.setStatusBar(self.statusbar)
self.retranslateUi(mainWindow)
QtCore.QMetaObject.connectSlotsByName(mainWindow)
mainWindow.setTabOrder(self.lineedit_api, self.api_amount)
mainWindow.setTabOrder(self.api_amount, self.dropdown_apiunit)
mainWindow.setTabOrder(self.dropdown_apiunit, self.pb_apiinsert)
mainWindow.setTabOrder(self.pb_apiinsert, self.lineedit_ExcipientName)
mainWindow.setTabOrder(self.lineedit_ExcipientName, self.lineedit_excipientamount)
mainWindow.setTabOrder(self.lineedit_excipientamount, self.dropdown_excipientunit)
mainWindow.setTabOrder(self.dropdown_excipientunit, self.pb_excipientinsert)
mainWindow.setTabOrder(self.pb_excipientinsert, self.ItemTable)
mainWindow.setTabOrder(self.ItemTable, self.textEdit_comment)
mainWindow.setTabOrder(self.textEdit_comment, self.pb_BatchRegisterLabel)
mainWindow.setTabOrder(self.pb_BatchRegisterLabel, self.lineedit_projectno)
mainWindow.setTabOrder(self.lineedit_projectno, self.lineedit_formulationno)
mainWindow.setTabOrder(self.lineedit_formulationno, self.lineedit_apino)
mainWindow.setTabOrder(self.lineedit_apino, self.lineedit_batchno)
mainWindow.setTabOrder(self.lineedit_batchno, self.dropdown_processtype)
mainWindow.setTabOrder(self.dropdown_processtype, self.pb_removeTableEntry)
def retranslateUi(self, mainWindow):
_translate = QtCore.QCoreApplication.translate
mainWindow.setWindowTitle(_translate("mainWindow", "MainWindow"))
self.lineedit_api.setText(_translate("mainWindow", "API NNCNo"))
self.pb_apiinsert.setText(_translate("mainWindow", "Insert"))
self.api_amount.setText(_translate("mainWindow", "Amount"))
self.dropdown_apiunit.setItemText(0, _translate("mainWindow", "mg"))
self.dropdown_apiunit.setItemText(1, _translate("mainWindow", "mg/tablet"))
self.dropdown_apiunit.setItemText(2, _translate("mainWindow", "% (w/w)"))
self.dropdown_apiunit.setItemText(3, _translate("mainWindow", "mg/capsule"))
self.pb_BatchRegisterLabel.setText(_translate("mainWindow", "Batch Register and Label"))
self.pb_removeTableEntry.setText(_translate("mainWindow", "Remove"))
self.label.setText(_translate("mainWindow", "-"))
self.label_2.setText(_translate("mainWindow", "-"))
self.label_3.setText(_translate("mainWindow", "-"))
self.dropdown_processtype.setItemText(1, _translate("mainWindow", "option 1"))
self.dropdown_processtype.setItemText(2, _translate("mainWindow", "option 2"))
self.dropdown_processtype.setItemText(3, _translate("mainWindow", "option 3"))
self.dropdown_processtype.setItemText(4, _translate("mainWindow", "option 4"))
self.dropdown_processtype.setItemText(5, _translate("mainWindow", "option 5"))
self.dropdown_processtype.setItemText(6, _translate("mainWindow", "option 6"))
self.dropdown_processtype.setItemText(7, _translate("mainWindow", "option 7"))
self.dropdown_processtype.setItemText(8, _translate("mainWindow", "User specify"))
self.label_4.setText(_translate("mainWindow", "Process Type"))
self.textEdit_comment.setHtml(_translate("mainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.label_5.setText(_translate("mainWindow", "Comment"))
self.label_6.setText(_translate("mainWindow", "NNC No"))
self.PushButton_NNCnoImport.setText(_translate("mainWindow", "Import"))
self.pb_formulationRegister.setText(_translate("mainWindow", "Register Formulation"))
self.TextEdit_api.setHtml(_translate("mainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.TextEdit_Excipient.setHtml(_translate("mainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.PushButton_Scan.setText(_translate("mainWindow", "Scan"))
self.label_7.setText(_translate("mainWindow", "Comments"))
self.lineedit_ExcipientName.setText(_translate("mainWindow", "Excipient Name"))
self.lineedit_excipientamount.setText(_translate("mainWindow", "Amount"))
self.dropdown_excipientunit.setItemText(0, _translate("mainWindow", "mg"))
self.dropdown_excipientunit.setItemText(1, _translate("mainWindow", "mg/tablet"))
self.dropdown_excipientunit.setItemText(2, _translate("mainWindow", "% (w/w)"))
self.dropdown_excipientunit.setItemText(3, _translate("mainWindow", "mg/capsule"))
self.pb_excipientinsert.setText(_translate("mainWindow", "Insert"))
class MainWindow(QtWidgets.QMainWindow, Ui_mainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
#upon initiation store the path to the different REST calls
self.url_standardcomponent = "http://somewhere"
#self.url_auth = " http://somwhere"
#self.username = 'username'
#self.password = 'password' #This must be changed later using Keberos-requests
#Import the standard component
# tool.import_standardcomponent(self)
self.SCL_Id = ["aaa", "bbb", "ccc"]
self.SCL_IdCompound = ["xxx", "yyy", "zzz"]
self.SCL_Name = ["111", "222", "333"]
self.SCL_OtherNames = ["PPP", "QQQ", "RRR"]
#Prepare the model for completer
self.model = QtGui.QStandardItemModel()
#The StandardModelItem only accepts string and not int, therefore a conversion is required
Id = [str(thing) for thing in self.SCL_Id]
IdCompound = [str(thing) for thing in self.SCL_IdCompound]
ziplist1 = list(zip(Id, IdCompound, self.SCL_Name))
ziplist2 = list(zip(Id, IdCompound, self.SCL_OtherNames))
#The idea here is to create a list with 3 columns. The 1., 2. columns being Id and IdCompounds. The 3rd comlumn is contains Name.
#Once done, the list will be append with OtherNames in the 3rd column. Reason being QCompleter can only match one column. Therefore
#Name and OtherNames have to be in 3rd column
for name in ziplist1:
row = list()
for col in name:
cell = QtGui.QStandardItem(col) #Has made sure that everything is a string
row.append(cell)
self.model.appendRow(row)
for name in ziplist2:
row = list()
for col in name:
cell = QtGui.QStandardItem(col)
row.append(cell)
self.model.appendRow(row)
#Prepare the completer
self.completer = QtWidgets.QCompleter()
self.completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.completer.setCompletionColumn(2) #Will use 2nd column containing both Name and OtherNames for completion
self.completer.setModel(self.model)
#I get the described error when running the below line. Also I have a question, does bracket [QtCore.QMOdelIndex] mean that the class is provided as a list?
self.completer.activated[QtCore.QModelIndex].connect(self.onActivated)
self.lineedit_ExcipientName.setCompleter(self.completer)
@QtCore.pyqtSlot(QtCore.QModelIndex)
def onActivated(self, index):
_id = index.sibling(index.row(), 0).data()
_id_compound = index.sibling(index.row(), 1).data()
text = index.data()
print(_id, _id_compound, text)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
(1) Using the Generated Code
(2) https://stackoverflow.com/a/46545116/6622587