使用 "QWidget *QLayoutItem::widget()" 会引发段错误(进入 qobjectdefs_impl.h)
Using "QWidget *QLayoutItem::widget()" throws a segment-fault (into qobjectdefs_impl.h)
我在 QTabWidget 选项卡中使用 QTabWidget(s),当我尝试获取存储在 "parent" QTabWidget 选项卡布局中的 "child" QTabWidget 时,我有一个段错误。
PS : 我正在使用 Qt Creator v4.8.1、Qtv5.6.3 和 Windows 7 64 位 OS(VBox v6.0.4 下的 VM)
最初,以下行抛出错误
dbTablesTabWidget = static_cast<QTabWidget*>(ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget());
我试过不带 "static_cast" 的下面一行,但错误总是出现
QWidget *widget = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
我最后一次尝试(没有 return QWidget 指针)总是出现相同的 "segment-fault" 错误。
ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
我不明白的是下面一行(第一个 for 循环中的第一行)
QString itemClass = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget()->metaObject()->className();
工作正常,尽管它包含相同的 "base code"。
段错误出现在 "qobjectdefs_impl.h" 文件中:
1 MainWindow::addRow mainwindow.cpp 298 0x403de6
2 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (MainWindow:: *)()>::call(void (MainWindow:: *)(), MainWindow *, void * *) qobjectdefs_impl.h 501 0x410175
3 QtPrivate::FunctionPointer<void (MainWindow:: *)()>::call<QtPrivate::List<>, void>(void (MainWindow:: *)(), MainWindow *, void * *) qobjectdefs_impl.h 520 0x4103e2
4 QtPrivate::QSlotObject<void (MainWindow:: *)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void * *, bool *) qobject_impl.h 143 0x410243
5 QtPrivate::QSlotObjectBase::call qobject_impl.h 124 0x6ba5d241
6 QMetaObject::activate qobject.cpp 3715 0x6b8fc213
7 QMetaObject::activate qobject.cpp 3595 0x6b8fbc3e
8 QAbstractButton::clicked moc_qabstractbutton.cpp 307 0x9c0685
9 QAbstractButtonPrivate::emitClicked qabstractbutton.cpp 404 0x9be459
10 QAbstractButtonPrivate::click qabstractbutton.cpp 397 0x9be3f4
11 QAbstractButton::mouseReleaseEvent qabstractbutton.cpp 1002 0x9bf6f7
12 QWidget::event qwidget.cpp 8757 0x8f6881
13 QAbstractButton::event qabstractbutton.cpp 959 0x9bf56c
14 QPushButton::event qpushbutton.cpp 673 0xa55168
15 QApplicationPrivate::notify_helper qapplication.cpp 3804 0x8bf880
16 QApplication::notify qapplication.cpp 3277 0x8bd5f1
17 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1015 0x6b8d37dd
18 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 228 0xc2fb5d
19 QApplicationPrivate::sendMouseEvent qapplication.cpp 2773 0x8bc2cb
20 QWidgetWindow::handleMouseEvent qwidgetwindow.cpp 607 0x90f314
... <plus>
下面是 addRow 方法的摘录("custom" 在单击 QPushButton 后调用的专用槽)
// var
int dbIndex = ui->tabWidget->currentIndex();
int tableIndex = 0;
QTabWidget *dbTablesTabWidget;
// Détection de l'index de l'item du layout de l'onglet de la BDD actuellement sélectionné
// -> Détection de la position du widget (jeu d'onglets des tables) dans le layout pour récupérer l'index de la table actuelle.
for (int i=0; i<ui->tabWidget->currentWidget()->layout()->count(); i++)
{
QString itemClass = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget()->metaObject()->className();
qDebug(itemClass.toLatin1());
if (itemClass == "QTabWidget")
{
qDebug("Cet élément est un QTabWidget !!!");
//*** The following line throws a segment fault ***
//dbTablesTabWidget = static_cast<QTabWidget*>(ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget());
//QWidget *widget = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
tableIndex = dbTablesTabWidget->currentIndex();
}
}
我是 Qt 的新手,我不知道段错误可能来自哪里。
编译过程OK,请看下面(法文版)
15:53:12: Configuration inchangée, étape qmake sautée.
15:53:12: Débute : "C:\Qt\Tools\mingw492_32\bin\mingw32-make.exe" -j1
C:/Qt/Tools/mingw492_32/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory 'E:/Projects_Info_Slink/_Training/C++/QTCreatorProject/DataBaseViewerGUI/build-DataBaseViewerGUI-Desktop_Qt_5_6_3_MinGW_32bit-Debug'
mingw32-make[1]: Nothing to be done for 'first'.
mingw32-make[1]: Leaving directory 'E:/Projects_Info_Slink/_Training/C++/QTCreatorProject/DataBaseViewerGUI/build-DataBaseViewerGUI-Desktop_Qt_5_6_3_MinGW_32bit-Debug'
15:53:13: Le processus "C:\Qt\Tools\mingw492_32\bin\mingw32-make.exe" s'est terminé normalement.
15:53:13: Temps écoulé : 00:01.
您在 tabwidget 中的页面可以包含任何小部件以及子选项卡小部件。
为简单起见,您可以尝试以下方法:
//GET YOUR CURRENT PAGE IN FIRST TAB WIDGET
QWidget *widget = ui->tabWidget->currentWidget();
//FROM THE CURRENT PAGE FIND THE CHILD TAB WIDGETS
QList<QTabWidget*> tabWidgets = widget->findChildren<QTabWidget*>();
//USE THE FOUND WIDGET FOR YOUR PURPOSE. DO SOME SAFETY CHECKS FOR LIST.
QTabWidget* requiredTabWidget = tabWidgets[0];
我终于找到错误了:
我应该使用 layout()->itemAt(i)
而不是 layout()->takeAt(i)
。
它解释了为什么第二次出现错误。
takeAt
从列表中删除该项目,因此在下次调用时,该项目不存在于列表中。
PS :对于 QList 对象,这是 at
而不是 itemAt
从元素列表中获取元素。
我在 QTabWidget 选项卡中使用 QTabWidget(s),当我尝试获取存储在 "parent" QTabWidget 选项卡布局中的 "child" QTabWidget 时,我有一个段错误。
PS : 我正在使用 Qt Creator v4.8.1、Qtv5.6.3 和 Windows 7 64 位 OS(VBox v6.0.4 下的 VM)
最初,以下行抛出错误
dbTablesTabWidget = static_cast<QTabWidget*>(ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget());
我试过不带 "static_cast" 的下面一行,但错误总是出现
QWidget *widget = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
我最后一次尝试(没有 return QWidget 指针)总是出现相同的 "segment-fault" 错误。
ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
我不明白的是下面一行(第一个 for 循环中的第一行)
QString itemClass = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget()->metaObject()->className();
工作正常,尽管它包含相同的 "base code"。
段错误出现在 "qobjectdefs_impl.h" 文件中:
1 MainWindow::addRow mainwindow.cpp 298 0x403de6
2 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (MainWindow:: *)()>::call(void (MainWindow:: *)(), MainWindow *, void * *) qobjectdefs_impl.h 501 0x410175
3 QtPrivate::FunctionPointer<void (MainWindow:: *)()>::call<QtPrivate::List<>, void>(void (MainWindow:: *)(), MainWindow *, void * *) qobjectdefs_impl.h 520 0x4103e2
4 QtPrivate::QSlotObject<void (MainWindow:: *)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void * *, bool *) qobject_impl.h 143 0x410243
5 QtPrivate::QSlotObjectBase::call qobject_impl.h 124 0x6ba5d241
6 QMetaObject::activate qobject.cpp 3715 0x6b8fc213
7 QMetaObject::activate qobject.cpp 3595 0x6b8fbc3e
8 QAbstractButton::clicked moc_qabstractbutton.cpp 307 0x9c0685
9 QAbstractButtonPrivate::emitClicked qabstractbutton.cpp 404 0x9be459
10 QAbstractButtonPrivate::click qabstractbutton.cpp 397 0x9be3f4
11 QAbstractButton::mouseReleaseEvent qabstractbutton.cpp 1002 0x9bf6f7
12 QWidget::event qwidget.cpp 8757 0x8f6881
13 QAbstractButton::event qabstractbutton.cpp 959 0x9bf56c
14 QPushButton::event qpushbutton.cpp 673 0xa55168
15 QApplicationPrivate::notify_helper qapplication.cpp 3804 0x8bf880
16 QApplication::notify qapplication.cpp 3277 0x8bd5f1
17 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1015 0x6b8d37dd
18 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 228 0xc2fb5d
19 QApplicationPrivate::sendMouseEvent qapplication.cpp 2773 0x8bc2cb
20 QWidgetWindow::handleMouseEvent qwidgetwindow.cpp 607 0x90f314
... <plus>
下面是 addRow 方法的摘录("custom" 在单击 QPushButton 后调用的专用槽)
// var
int dbIndex = ui->tabWidget->currentIndex();
int tableIndex = 0;
QTabWidget *dbTablesTabWidget;
// Détection de l'index de l'item du layout de l'onglet de la BDD actuellement sélectionné
// -> Détection de la position du widget (jeu d'onglets des tables) dans le layout pour récupérer l'index de la table actuelle.
for (int i=0; i<ui->tabWidget->currentWidget()->layout()->count(); i++)
{
QString itemClass = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget()->metaObject()->className();
qDebug(itemClass.toLatin1());
if (itemClass == "QTabWidget")
{
qDebug("Cet élément est un QTabWidget !!!");
//*** The following line throws a segment fault ***
//dbTablesTabWidget = static_cast<QTabWidget*>(ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget());
//QWidget *widget = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
tableIndex = dbTablesTabWidget->currentIndex();
}
}
我是 Qt 的新手,我不知道段错误可能来自哪里。 编译过程OK,请看下面(法文版)
15:53:12: Configuration inchangée, étape qmake sautée.
15:53:12: Débute : "C:\Qt\Tools\mingw492_32\bin\mingw32-make.exe" -j1
C:/Qt/Tools/mingw492_32/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory 'E:/Projects_Info_Slink/_Training/C++/QTCreatorProject/DataBaseViewerGUI/build-DataBaseViewerGUI-Desktop_Qt_5_6_3_MinGW_32bit-Debug'
mingw32-make[1]: Nothing to be done for 'first'.
mingw32-make[1]: Leaving directory 'E:/Projects_Info_Slink/_Training/C++/QTCreatorProject/DataBaseViewerGUI/build-DataBaseViewerGUI-Desktop_Qt_5_6_3_MinGW_32bit-Debug'
15:53:13: Le processus "C:\Qt\Tools\mingw492_32\bin\mingw32-make.exe" s'est terminé normalement.
15:53:13: Temps écoulé : 00:01.
您在 tabwidget 中的页面可以包含任何小部件以及子选项卡小部件。
为简单起见,您可以尝试以下方法:
//GET YOUR CURRENT PAGE IN FIRST TAB WIDGET
QWidget *widget = ui->tabWidget->currentWidget();
//FROM THE CURRENT PAGE FIND THE CHILD TAB WIDGETS
QList<QTabWidget*> tabWidgets = widget->findChildren<QTabWidget*>();
//USE THE FOUND WIDGET FOR YOUR PURPOSE. DO SOME SAFETY CHECKS FOR LIST.
QTabWidget* requiredTabWidget = tabWidgets[0];
我终于找到错误了:
我应该使用 layout()->itemAt(i)
而不是 layout()->takeAt(i)
。
它解释了为什么第二次出现错误。
takeAt
从列表中删除该项目,因此在下次调用时,该项目不存在于列表中。
PS :对于 QList 对象,这是 at
而不是 itemAt
从元素列表中获取元素。