I'm writing an investigation board program. It uses a database and displays geographical data. It has multiple security layers, and an investigation may be "public", or secured at one of several layers. Thus a user may be anonymous, or registered with a granted privilege level. So I'm testing opening a case as anonymous, and then logging in with an active case open. It should remain open and active once logged in. So far so good. A user should be able to open a new case from either the menu, or an exposed auto-generated list in a detachable toolbar.
So, I'm testing opening cases, logging in, changing the active case, logging out (which should close any active privileged case), etc.
I get an error the first time I choose to cancel out a "close" action on an active case in a "non-supported" manor. There is a menu selection to close cases, but there is a necessary error catch where a user can use a drop-down list to "deselect" the active case. At this point a Qmessage box asks the user if they want to close the active case. If the answer is no, then the combobox reselects the currently active case. This is done by shutting off events for the combobox and setting the currentText, and turning events back on. If I don't do this it triggers setting the active case as active again, and may have unintended consequences later on in future code. I'm writing with PyQt 5.15.6 and Python 3.10.12 on Linux Mint 21.3 Virginia 64 bit (sans cinnamon desktop as it conflicts with my preferred KDE desktop - couldn't even get the upgrade to work without removing it).
Console output of a typical test:
Active Case Title = Ó Duibhir Clan of Pallasgrean and it's uid = 1
User, xxx, Logged in
Active Case Title = Cunningham Clan of County Louth and it's uid = 2
Case remains open {added comment: this is from choosing the "No" button of the qMessagebox}
<b>qt.qpa.xcb: QXcbConnection: XCB error: 3 (BadWindow), sequence: 2465, resource id: 27269098, major code: 40 (TranslateCoords), minor code: 0</b>
Active Case Title = Ó Duibhir Clan of Pallasgrean and it's uid = 1
Active Case Title = Ó Duibhir Clan of Tipperary and it's uid = 3
Case closed
Active Case Title = Ó Duibhir Clan of Pallasgrean and it's uid = 1
Case remains open
User, xxx, Logged in
Active Case Title = Cunningham Clan of County Louth and it's uid = 2
Active Case Title = Ó Duibhir Clan of Pallasgrean and it's uid = 1
Case closed
User, xxx, logged out
Active Case Title = Ó Duibhir Clan of Pallasgrean and it's uid = 1
User, xxx, Logged in
Case remains open
Case closed
Active Case Title = Ó Duibhir Clan of Tipperary and it's uid = 3
Active Case Title = Cunningham Clan of County Louth and it's uid = 2
Case remains open
relevant code snippets:
def on_cmbCase_current_changed():
#print("Entered on_cmbCase_current_changed()")
if ( self.cmbCase.currentText() != 'Select a case' ):
#FIXME: Need "check if isDirty and handling" code here
self.hasCase = True
self.ActiveCase = self.cmbCase.currentText()
self.caseId = self.cmbCase.currentData()
self.actionClose.setEnabled(True)
print(f"Active Case Title = {self.ActiveCase} and it's uid = {self.caseId}")
else:
if self.hasCase:
qm = QMessageBox(QMessageBox.Question,"Close Active Investigation?","Close the Active Investigation?",QMessageBox.Yes | QMessageBox.No, self)
ok = qm.exec()
if (ok == qm.Yes):
#FIXME: Need to handle case isDirty condition
self.hasCase = False
self.ActiveCase = None
self.caseId = 0
self.actionClose.setEnabled(False)
print("Case closed")
else:
self.cmbCase.blockSignals(True)
self.cmbCase.setCurrentText(self.ActiveCase)
self.cmbCase.blockSignals(False)
print("Case remains open")
else: print("No case is open, nothing to do.")
...
def ResetControls():
self.cmbCase.blockSignals(True)
self.cmbCase.clear()
self.cmbCase.addItem('Select a case', 0)
self.caselist = pDB.GetCaseList(myConfig.creds, self.userid)
if self.caselist is not None:
for row in self.caselist:
self.cmbCase.addItem(row[0],row[1])
#Try and preserve currently selected Case is there is one
if self.hasCase:
if (self.ActiveCase == row[0]):
self.cmbCase.setCurrentText(row[0])
self.cmbCase.blockSignals(False)
...
def Login():
#print(f'Self = {self.objectName()}')
if not self.LoggedIn:
dlgLogin = qtl.cQLogin(self)
...
userid = dlgLogin.GetUserID()
if ok:
self.actionLog_In.setEnabled(False)
self.actionLogout.setEnabled(True)
self.LoggedIn = True
...
print(f"User, {user}, Logged in")
self.userName = user
self.userid = userid
ResetControls()
else:
print(f"Login for user, {user}, failed.")