can't find linker symbol for virtual table for 'QAbstractItemViewPrivate' value



  • Hi everybody,

    I'm facing an issue while developing my code for an user interface. I'm using Qt 4.8 on a Linux distro deployed with Yocto.
    Here a really simple snippet of my code:

    //	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;                 //!< View used to represent data list
        QStandardItemModel  *dataModel;                 //!< Data model visualized by the view
    }
    
    
    //	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() );
    }
    
    

    Problem has its origin when emitting signal 'request_GoToNext', that makes the application crash or the debug stop due to segmentation fault.
    What I can see is that, in QtCreator, the point where the application seems to fail is in the file qabstractitemview.cpp, more specific in this function:

    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;
    }
    

    To me it sounds really strange.
    After emitting the signal, the application should delete current panel and build another one: setting some 'qDebug' calls this seems to happen, deleting current panel (and its children) and creating a new one, but the application fails before showing the new panel.
    It seems like the program "exits" the slot 'onNext' after having delete everything related to MyWidget.

    Also, in teh Application Output of QtCreator I can read this message

    can't find linker symbol for virtual table for 'QAbstractItemViewPrivate' value

    NB - Observation
    If I rewrite the code inside my slot in this way

    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() );
    }
    

    Everything works fine! That's why it seems something related to "exit" slot call to me.

    Many thanks for your help


  • Lifetime Qt Champion

    Hi,

    Can you show the related code ?



  • Mmm, the related code to what?


  • Lifetime Qt Champion

    Sorry, I misread your original post.

    Can you reproduce that with a minimal compilable example ?

    By the way, what version of Qt 4.8 are you using ?



  • After some other tests, I think I've found which is the issue and how to solve it.

    Here a simplified snippet of my code, where there is a class Button used by a class Parent.
    When button is clicked, it could cause a panel change, or raise a message, or do some other actions (not detailed beause not relevant to the question).

    What I found is in slot onClicked of class Button: entering the first if, the program emits the signal request_GoToPrev, which cause the class Panel to delete current panel (and its childs, even compirsed the Button!) and raise a new one.
    But after emitting the signal and do all actions required, the program "comes back" to the point when it has emitted the signal and continue the instruction execution: when it reaches the second if it creashes because this is no more consistent.

    That's what it seems to be after my tests. Putting a return call just after the signal emission in the first if problem is solved.

    // 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...
    }
    
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.