PDA

View Full Version : signal acrorss different QStacked Widgets



hass26
24th February 2015, 20:16
I have a GUI with multiple tabs, where each tab contains widgets defined in their own class and .ui.

I am trying to implement "setCurrentIndex()" of the tabWidget when the user clicks on a pushbutton that could be in any of the tab pages.

Doing it the way below works, but it does not update the tab header/title that is active. For example, if I have a tab widget with page titles: tab0, tab1, tab2, and I change from tab0 to tab2 with setCurrentIndex(2). It will show the right content of tab2, but the tabWidget header still shows tab0 :confused: Any ideas why? or if there is a better implementation. Thanks

QObject *obj = new QStackedWidge;
foreach( QObject *obj, this->parent()->parent()->children())
{
if(obj->objectName()=="qt_tabwidget_stackedwidget")
{
QStackedWidget *tab = static_cast<QStackedWidget*>(obj);
tab->setCurrentIndex(2);
}
}

d_stranz
25th February 2015, 03:25
If you want tabs, why are you using QStackedWidget and not QTabWidget?

hass26
25th February 2015, 20:00
Because I cannot find any widget defined as tabwidget using children(), even though the tab was defined originally as a QTabWidget.

The program compiles when I use QTabWidget rather than QStackedWidget; but it crashes without any error messages at run time.

Is there a better way to do? Thanks.

Kryzon
25th February 2015, 21:31
If you're creating the QTabWidget and QPushButtons yourself (regardless if you're using Qt Designer or directly by code) then you can subclass them.
By subclassing the QTabWidget, you can add a slot to it that receives the 'clicked' signals from the buttons.
By subclassing the QPushButtons, you can add a member property that indicates the tab index that you should switch to.

The QTabWidget knows the widgets that you're adding as pages to it (or you can retrieve them with widget(index) if they are already added), so its new slot can easily be connected to each of the signals from the buttons since you have visibility of them.
The slot could be something like this:


void MyTabWidget::onButtonClick()
{
MyPushButton* button = qobject_cast< MyPushButton* >( sender() );
setCurrentIndex( button.getDesiredIndex() );
}

If you're using Qt Designer, you'll need promote (http://doc.qt.io/qt-5/designer-using-custom-widgets.html) the QTabWidget and the QPushButtons to their corresponding subclasses.
EDIT: Forgot the scope operator, and changed from static_cast to qobject_cast as the below suggestion.

d_stranz
25th February 2015, 23:09
Because I cannot find any widget defined as tabwidget using children(), even though the tab was defined originally as a QTabWidget.

What are you calling children() on? The tab widget itself? If so, of course you won't see any children of type QTabWidget.

And static_cast<> is absolutely the wrong thing to do. A static cast says, "I don't care what this object really is, treat it as though it was an object of the type I am casting it to", so of course you can cast any pointer to QStackedWidget or anything else, but that doesn't make it so. No wonder your program crashes.

If you are trying to cast a Qt object instance, you use qobject_cast< QTabWidget * >() and you check that the pointer that is returned is non-NULL before trying to use it.

hass26
26th February 2015, 03:09
Ok. I found a workaround solution, maybe not the most elegant but It works.


QObject *obj = parent->findChild<QTabWidget*>("pagesTabWidget");
QTabWidget *tab = qobject_cast<QTabWidget*>(obj);
tab->setCurrentIndex(1);

d_stranz
26th February 2015, 17:30
I found a workaround solution, maybe not the most elegant but It works.

No, it's guaranteed to crash if either the "obj" or "tab" pointers are NULL.

Why is it so hard for people to understand that the way you avoid segfaults is to check pointers for NULL before using them?

hass26
7th March 2015, 10:52
Yes I did. Thanks.


No, it's guaranteed to crash if either the "obj" or "tab" pointers are NULL.

Why is it so hard for people to understand that the way you avoid segfaults is to check pointers for NULL before using them?