PDA

View Full Version : automate QCompleter selection



ottawaDan
15th July 2013, 18:56
Good afternoon,

We have implemented a test-mode for the application we have developed. Essentially, when the test mode is selected, a separate thread is launched and we are using QMetaObject::invokeMethod( ...) on the different controls to simulate user interaction, entries, and so on. The SW also uses QStateMachine framework.

A recent change includes the use of QCompleter on a QLineEdit, and QState transitions when the QLineEdit is modified and a selection is made is based on QSignalTransition as shown here


class AutoCompleterTransition : public QSignalTransition
{
public:
AutoCompleterTransition( AcquisitionWindow* acquisitionWindow, QCompleter* completer)
: QSignalTransition( completer, SIGNAL( activated( const QModelIndex&))),
m_acquisitionWindow( acquisitionWindow),
m_completer( completer)
{
}

virtual bool eventTest( QEvent *e)
{
if (!QSignalTransition::eventTest( e))
return false;
QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(e);
QModelIndex modelIndex = se->arguments().at( 0).value<QModelIndex>();
return( modelIndex.isValid());
}

virtual void onTransition( QEvent *e)
{
QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(e);
QModelIndex modelIndex = se->arguments().at( 0).value<QModelIndex>();
m_acquisitionWindow->insertCompletion( modelIndex);
qDebug( "%s: model index: row: %d, col: %d",
__FUNC_NAME__, modelIndex.row(), modelIndex.column());
}

private:
AcquisitionWindow* m_acquisitionWindow;
QCompleter* m_complete
};


Where the completer is instantiated and initialized as follow:

selectCompleter = new QCompleter( this);
model = new QStandardItemModel( selectCompleter);

selectCompleter->setCompletionMode( QCompleter::PopupCompletion);
selectCompleter->setModel( model);
selectCompleter->setModelSorting( QCompleter::CaseInsensitivelySortedModel);
selectCompleter->setCaseSensitivity( Qt::CaseInsensitive);
selectCompleter->setWrapAround( true);

QTreeView* popupView = new QTreeView;
selectCompleter->setPopup( popupView);

popupView->setSelectionMode( QAbstractItemView::SingleSelection);
popupView->setSelectionBehavior( QAbstractItemView::SelectRows);
popupView->setEditTriggers( QAbstractItemView::NoEditTriggers);
popupView->setAlternatingRowColors( true);

popupView->setRootIsDecorated(false);
popupView->header()->hide();
popupView->header()->setStretchLastSection( false);

This QState transition works well when running in 'normal' mode, but in 'test mode', I cannot trigger the transition. I have tried different approaches; changing the setCompletionMode to QCompleter::InlineCompletion; using QCompleter::setCurrentIndex( 0) to select the first entry in the popup for instance without success. Note that after call QCompleter::setCurrentIndex( 0), QModelIndex modelIndex = completer->currentIndex() reports the correct selection.

How can I then simulate the selection in the popup?

Thanks in advance
Daniel

ottawaDan
16th July 2013, 15:42
Hi again,

I guess another way to look at this problem is 'how to programmatically make a selection in a QTreeView (that is the pop-up view used in this example) using QMetaObject::invokeMethod( ...)?"

My investigation continues and I will report back if I find a solution. Meanwhile, your help is much appreciated.

Daniel

ottawaDan
18th July 2013, 21:15
Here is the code used to automate the selection from the QCompleter popup (using QTreeView)


QCompleter* completer = patientInputWidget->txtLastName->completer();
if (completer) {
// The QCompleter has been set, force the selection of the first entry
completer->setCurrentRow( 0);
QModelIndex modelIndex = completer->currentIndex();
QMetaObject::invokeMethod( completer, "activated", Qt::BlockingQueuedConnection, Q_ARG( QModelIndex, modelIndex));
...
}

This code is executed on a different thread than the GUI thread.