PDA

View Full Version : QTabWidget - prevent change of tab without disabling tabs



ashtray4241
5th January 2015, 11:03
Hi,

This question has actually been asked, but I am not sure what was the context of it.
Also, the solution in that thread is not clear, so I will ask the question again with my context.

In a QTabWidget, I want the tab buttons to be enabled, but the tab switching needs to be prevented for some tabs.
The use of this is in the below scenario.

There are two tabs - "User" and "Admin".
When "Admin" is clicked, a dialog/popup to ask for user name and password needs to be displayed, and only on successful login, tab should change to Admin.
But "User" tab can be clicked and User screen should be displayed.
If I disable the "Admin" Tab, I cannot click it to show the popup.
And if I don't block the opening of Admin tab page, unauthorized viewing will be there.

Can anyone please suggest me how to proceed.

Is there any event that leads to TabChange (i.e. before the Tab is changed)

Regards,
Ash

d_stranz
5th January 2015, 18:33
I do not know when the QTabWidget::tabBarClicked() signal is emitted - before or after the tab is changed. If it is emitted before the tab is changed, then that is probably what you want. However, I do not think there is any way of preventing the change if the user doesn't enter the right credentials for Admin.

Here is an alternative: Create the QWidget you use for the content of the Admin page, but set its visible state to false when you create it. This way, when the tab appears, the contents will be invisible. Implement a handler for the QTabWidget::currentChanged() signal. When you receive it for your Admin page, post the dialog to log the user in as Admin. If the login succeeds, set the widget to visible. When the user leaves the page, set the widget back to invisible.

ashtray4241
8th January 2015, 05:31
I do not know when the QTabWidget::tabBarClicked() signal is emitted - before or after the tab is changed. If it is emitted before the tab is changed, then that is probably what you want. However, I do not think there is any way of preventing the change if the user doesn't enter the right credentials for Admin.

Here is an alternative: Create the QWidget you use for the content of the Admin page, but set its visible state to false when you create it. This way, when the tab appears, the contents will be invisible. Implement a handler for the QTabWidget::currentChanged() signal. When you receive it for your Admin page, post the dialog to log the user in as Admin. If the login succeeds, set the widget to visible. When the user leaves the page, set the widget back to invisible.

Hi d_stranz. Thanks for the suggested solution. QTabWidget::tabBarClicked() didn't help me.
Your other solution was good, i.e. keeping the main widget as invisible. But it had one design issue that the Admin tab was shown as selected, even if the widget is invisible.

I actually achieved the required behavior by overriding mouseEvents.
I just think that these are few controls that should be provided natively in QT.

In any case, if anybody needs, I can post the working sample code for this above requirement/behavior. :)

anujbhasinplp
20th September 2016, 11:04
Hi ashtray 4241....can you please share the working sample code.:)

anujbhasinplp
23rd September 2016, 11:12
I was able to implement this using an eventfilter in PyQt.

Sample code:

self.tabWidget.tabBar().installEventFilter(self)

def eventFilter(self, object, event):
try:
if object == self.tabWidget.tabBar() and event.type() in [QtCore.QEvent.MouseButtonPress, QtCore.QEvent.MouseButtonRelease] and event.button() == QtCore.Qt.LeftButton
# tabIndex = object.tabAt(event.pos())
if event.type() == QtCore.QEvent.MouseButtonPress:
if self.tab_1.search_inprogress is True:
dlg = custom_dialog(width=300, height=100)
dlg.pushButton_no.setCheckable(True)
dlg.pushButton_yes.setCheckable(True)
dlg.pushButton_no.setText("No")
dlg.pushButton_yes.setText("Yes")
dlg.pushButton_yes.clicked.connect(self.tab_1.stop _progress)
dlg.label_text.setText("Search operation is underway. Would you like to stop the operation and proceed?")
if dlg.exec_() == QtGui.QDialog.Accepted:
dlg.close()
if dlg.pushButton_no.isChecked():
return True
elif dlg.pushButton_yes.isChecked():
return False
else:
return False
except Exception as e:
print "Exception raised in eventfilter", e