[Interest] setting focus to a QTableWidget Row

Rene Decartes rene.decartes.too at gmail.com
Fri Jul 24 21:54:55 CEST 2015


I am having trouble getting the 'new/next' row in a QTableWidget to have focus.
I have a QTableWidget to hold authors names which will allow the user to add new 
author names to the 'list' of authors of a book. I am using a subclassed 
QItemDelegate and QTableWidgetItem similar to those in the spreadsheet example
from Qt.

The delegate editor is a QLineEdit with a QSqlQueryModel, QTableView, and QCompleter.

My approach is to always have an 'empty' row in the QTableWidget to allow the addition
of authors. When the user enters a new author and hits return, a new row is added. I 
would like this new row to receive focus. When I set this to happen, the new row is not editable until I click on it, or tab out and back it. I am uncertain what I am missing.

(ellipses represents other code)

@
#ifndef AUTHORDELEGATE_H__
#include "bookswindow.h++"

#include <QItemDelegate>
#include <QDebug>

class AuthorDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    AuthorDelegate(QObject *parent = 0);
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
                          const QModelIndex &index) const;
    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const;

private slots:
    void commitAndCloseEditor() ;
};

#include <QtWidgets>

AuthorDelegate::AuthorDelegate(QObject *parent)
        : QItemDelegate(parent)
{
    qDebug() << "AuthorDelegate::AuthorDelegate" ;
    qDebug() << "AuthorDelegate::AuthorDelegate this: " << this ;
    qDebug() << "AuthorDelegate::AuthorDelegate parent: " << parent ;
}

QWidget *
AuthorDelegate::createEditor( QWidget *parent,
                              const QStyleOptionViewItem &,
                              const QModelIndex &index ) const
{
    QLineEdit *editor = new QLineEdit( parent ) ;
    editor->setMaximumWidth( 255) ;

    QSqlQueryModel * editorModel = new QSqlQueryModel( editor ) ;
    editorModel->setQuery( "SELECT authno , fullname FROM authorsView WHERE authNo > -1 ORDER BY fullname" ) ;

    QCompleter * editorCompleter = new QCompleter( editorModel ) ;
    editorCompleter->setModel( editorModel ) ;
    editorCompleter->setCompletionColumn( 1 ) ;
    editorCompleter->setMaxVisibleItems( 7 ) ;
    editorCompleter->setModelSorting( QCompleter::CaseInsensitivelySortedModel ) ;
    editorCompleter->setCompletionMode( QCompleter::UnfilteredPopupCompletion ) ;
    editorCompleter->setCaseSensitivity( Qt::CaseInsensitive ) ;

    QTableView * editorView = new QTableView ;
    editorCompleter->setPopup( editorView ) ;

    int width = editorView->columnWidth( 0  ) ;
    width += editorView->columnWidth( 1  ) ;
    editorView->setColumnHidden( 0 , true ) ;
    editorView->hideColumn( 0 ) ;
    editorView->setColumnWidth( 1 , 4 * width ) ;
    editorView->setMinimumWidth( width ) ;

    editorView->verticalHeader()->hide() ;
    editorView->horizontalHeader()->hide() ;
    editorView->verticalHeader()->setStretchLastSection( true ) ;
    editorView->verticalHeader()->setSectionResizeMode( 1 , 
                                  QHeaderView::ResizeToContents ) ;

    editor->setCompleter( editorCompleter ) ;
    editorView->adjustSize() ;

    connect( editor , SIGNAL( editingFinished() ) ,
             this , SLOT( commitAndCloseEditor() ) ) ;

    return editor ;
}

void
AuthorDelegate::commitAndCloseEditor()
{
    QLineEdit *editor = qobject_cast<QLineEdit *>( sender() ) ;

    emit commitData( editor ) ;
    emit closeEditor( editor ) ;
}

void
AuthorDelegate::setEditorData( QWidget *editor,
                               const QModelIndex &index ) const
{
    qDebug() << "AuthorDelegate::setEditor" ;
    QLineEdit *edit = qobject_cast<QLineEdit*>( editor ) ;

    if ( edit )
    {
        edit->setText( index.model()->data( index, Qt::EditRole ).toString() ) ;
        return ;
    }
}

void
AuthorDelegate::setModelData( QWidget *editor ,
                              QAbstractItemModel *model ,
                              const QModelIndex &index ) const
{
    qDebug() << "AuthorDelegate::setModelData" ;
    QLineEdit *edit = qobject_cast<QLineEdit *>( editor ) ;
    if ( edit )
    {
        model->setData( index, edit->text() ) ;
        return ;
    }
}


// --- panel contain tablewidget

#include <QtWidgets>
#include <QSqlQueryModel>
#include <QSqlQuery>
#include "bookswindow.h++"
#include "authordelegate.h++"
#include "authoritem.h++"
#include <iostream>
#include <string.h>

.........

void
BooksWindow::createPanel()
{
qDebug() << "start of createPanel" ;

    panel = new QTableWidget( 1 , 1 , this ) ;
    panel->adjustSize() ;

    authorLabel = new QLabel( tr( "Author" ) ) ;
    authorLabel->setBuddy( panel ) ;

    panel->horizontalHeader()->hide() ;
    panel->verticalHeader()->hide() ;
    panel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    int width = panel->columnWidth( 0 ) ;
    panel->setColumnWidth( 0 , 3 * width ) ;

    panel->setItemPrototype( panel->item( 0 , 0 ) ) ;
    panel->setItemDelegate( new AuthorDelegate( this ) ) ;
qDebug() << "BooksWindow::createPanel this: " << this ;

    fillHash() ;

    connect( panel , SIGNAL( itemChanged( QTableWidgetItem *  ) ) ,
             this , SLOT( checkPanelState( QTableWidgetItem *  ) ) ) ;

qDebug() << "end of createPanel" ;
}

void
BooksWindow::keyPressEvent( QKeyEvent *event )
{
    if ( Qt::Key_Return == event->key() )
	{
qDebug() << "BooksWidow::kepPressEventKey pressed: Return" ;
	}
	else if ( Qt::Key_Enter == event->key() )
	{
qDebug() << "BooksWidow::kepPressEventKey pressed: Enter" ;
	}

	QWidget::keyPressEvent( event ) ;
}

void
BooksWindow::checkPanelState( QTableWidgetItem * item )
{
    QString number( item->data( Qt::UserRole ).toString() ) ;
    QString name( item->text() ) ;

    int row = item->row() ;
    int column = item->column() ;
    int rowCount = panel->rowCount() ;

    // is this the last row, if so add another
    if ( ( ( rowCount - 1 ) == row ) && validateAuthor( name , row ) )
    {
        panel->insertRow( rowCount ) ;
        QTableWidgetItem *item = panel->item( rowCount , 0 ) ;
        // set the author name
        item = static_cast<AuthorItem *>( panel->item( rowCount , 0 ) ) ;

        if ( !item )
        {
            panel->setItem( rowCount , 0 , new AuthorItem( "" ) ) ;
        }
        else
        {
            item->setText( "" ) ;
        }

        panel->setFocus() ;
		panel->activateWindow() ;

        if ( panel->hasFocus() )
        {
qDebug() << "BooksWindow::checkPanelState has edit focus" ;
        }
        else
        {
qDebug() << "BooksWindow::checkPanelState does not have edit focus" ;
        }
    }
}

bool
BooksWindow::validateAuthor( QString &name , int row )
{
    // if it is a blank string, go no further
    if ( "" == name )
    {
        return false ;
    }

         << name << "count:" << authorHash.count( name ) ;
    // see if this is a valid author. if not
    // blank
    if ( authorHash.contains( name ) )
    {
        return true ;
    }
    else
    {
        QTableWidgetItem *item = panel->item( row , 0 ) ;

        if ( !item )
        {
            panel->setItem( row , 0 , new AuthorItem( "" ) ) ;
        }
        else
        {
            item->setText( "" ) ;
        }

        return false ;
    }
}

void
BooksWindow::fillHash()
{
    int value ;
    QString key ;

    QString sql( "SELECT authNo , fullName FROM authorsView " ) ;
    sql.append( "ORDER BY authNo" ) ;
    QSqlQuery query( sql ) ;

    if ( ! query.exec( sql ) )
    {
        showMessage( query ) ;
    }
    else
    {
        if ( ! query.first() )
        {
            showMessage( query ) ;
        }
        else
        {
            key.clear() ;
            authorHash.clear() ;
            value = query.value( 0 ).toInt() ;
            key.append( query.value( 1 ).toString() ) ;
            authorHash[ key ] = value ;

            while ( query.next() )
            {
                value = query.value( 0 ).toInt() ;
                key.clear() ;
                key.append( query.value( 1 ).toString() ) ;
                authorHash[ key ] = value ;
            }
        }

        query.finish() ;
    }
}

.............
@

Thanks for any input.



More information about the Interest mailing list