无法为QAbstractItemViewPrivate' QAbstractItemViewPrivate'找到虚拟表的链接器符号。值

时间:2017-11-23 16:17:46

标签: c++ qt4 signals-slots

我在为用户界面开发代码时遇到了问题。我在使用Yocto部署的Linux发行版上使用Qt 4.8。 这是我的代码的一个非常简单的片段:

//  MyWidget.h
class MyWidget : public QWidget
{
    Q_OBJECT

public:
    MyWidget( QWidget* parent );
    ~MyWidget();

signals:
    void request_GoToNext( QString );           //!< Go to next panel

private slots:
    void onNext( QModelIndex index );

private:
    QTableView          *tableView;          
    QStandardItemModel  *dataModel;              
}


//  MyWidget.cpp
MyWidget::MyWidget( QWidget *parent ) : QWidget(parent)
{
    this->tableView = new QTableView(this);
    this->dataModel = new QStandardItemModel();

    // "Fill-in" data model with the list of files in a specific directory
    ...

    connect( this->tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(onNext(QModelIndex)), Qt::UniqueConnection );
}

MyWidget::~MyWidget()
{
    disconnect( this->tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(onNext(QModelIndex)) );

    this->dataModel->clear();

    delete this->tableView;
    delete this->dataModel;
}

void MyWidget::onNext( QModelIndex index )
{
    emit this->request_GoToNext( this->dataModel->item(index.row(), index.column())->text() );
}

问题源于发出信号&#39; request_GoToNext&#39;,这会导致应用程序崩溃或调试因分段错误而停止。 我可以看到,在QtCreator中,应用程序似乎失败的地方在qabstractitemview.cpp文件中,在此函数中更具体:

QStyleOptionViewItemV4 QAbstractItemViewPrivate::viewOptionsV4() const
{
    Q_Q(const QAbstractItemView);
    QStyleOptionViewItemV4 option = q->viewOptions();
    if (wrapItemText)
        option.features = QStyleOptionViewItemV2::WrapText;
    option.locale = q->locale();
    option.locale.setNumberOptions(QLocale::OmitGroupSeparator);
    option.widget = q;
    return option;
}

对我来说这听起来很奇怪。 发出信号后,应用程序应删除当前面板并构建另一个面板:设置一些“qDebug”。调用这似乎发生了,删除当前面板(及其子节点)并创建一个新面板,但应用程序在显示新面板之前失败。 好像该计划&#34;退出&#34;插槽&#39; onNext&#39;删除与MyWidget相关的所有内容后。

此外,在QtCreator的应用程序输出中,我可以阅读此消息

无法找到虚拟表的链接符号,以便QAbstractItemViewPrivate&#39;值

NB - 观察 如果我以这种方式重写我的插槽中的代码

 void MyWidget::onNext( QModelIndex index )
 {
     QObject::startTimer(1);
     emit this->request_GoToNext( this->dataModel->item(index.row(), index.column())->text() );
 }

 void MyWidget::timerEvent( QTimerEvent *event )
 {
     QObject::killeTimer( event->timerId() );

     emit this->request_GoToNext( this->dataModel->item(index.row(), index.column())->text() );
 }

一切正常!这就是为什么它似乎与&#34;退出&#34;相关的原因。插槽给我打电话。

非常感谢你的帮助

1 个答案:

答案 0 :(得分:0)

经过其他一些测试,我认为我发现了哪个问题以及如何解决。

这是我的代码的简化片段,其中有类Parent使用的类Button。 单击按钮时,可能会导致面板更改,或发出消息,或执行其他操作(不详细因为与问题无关)。

我发现的是在按钮类的插槽 onClicked 中:输入第一个 if ,程序发出信号 request_GoToPrev < / em>,这会导致类 Panel 删除当前面板(及其子节点,甚至编译Button!)并引发一个新面板。 但是在发出信号并执行所需的所有操作之后,程序“返回”到它发出信号并继续执行指令的时候:当它到达第二个它因为这个不再一致。

这是我测试后的样子。在第一个 if 问题中的信号发射之后立即进行返回调用。

// HEADER: Button.h
class Button : public QPushButton
{
    Q_OBJECT

public:

    Button( QWidget *parent = 0 );
    ~Button();

signals:
    void request_GoToPrev();                    //!< Go to previous panel
    void request_GoToNext( QString );           //!< Go to next panel
    void signal_Error( int );                   //!< Error code

private slots:
    void onClicked();

private:
    typ_Button_tags *widgetTags;                //!< Pointer to the tags structure that defines the \ref Button widget
    typ_Shared      *privateCtx;                //!< Reference to runtime application structure
};

// C: Button.cpp
Button::Button( QWidget *parent )
    :
      QPushButton(parent)
{
    //  Do some settings, like: font, stylesheet, focus, size..
}

Button::~Button()
{
}

void Button::onClicked()
{
    //  Callback to be called when button clicked
    if( !this->widgetTags->callbackClick.isEmpty() )
    {
            emit this->request_GoToPrev();

            /*  !!! ATTENTION   !!!
             *
             *  Here the instruction return HAS to be written, otherwise the application crashes.
             *  In fact, when running, the signal 'request_GoToPrev' is sent, but the flow of the
             *  process should exit the call of this slot.
             *  Doing that, 'this' is no more consistent after having emitted the signal, so the
             *  application face a segmentation fault.
             */
            return;
    }


    //  Message box
    if( !this->widgetTags->msgText.isEmpty() )
    {
        //  Do some other actions on 'this'...
    }
}

// HEADER: Panel.h
class Panel : public QMainWindow
{
    Q_OBJECT

public:

    Panel( QWidget *parent = 0 );

private slots:
    void on_GoToNext(int index);
    void on_GoToPrevious();
    void on_Error(int errId);

private:
    Button *Btn;
};

// C: Panel.h
Panel::Panel( QWidget *parent )
    :
      QMainWindow(parent)
{
    //  Do some settings: font, stylesheet, focus, size...

    this->Btn = new Button( this );

        connect( this->Btn, SIGNAL(request_GoToPrev()), this, SLOT(on_GoToPrevious()), Qt::UniqueConnection );
    //  Do some actions to layout the button inside the panel
}

void Panel::on_GoToPrevious()
{  
    //  Do some check...

    delete this->Btn;

    //  Do some actions...
}