qt - A QLineEdit/QComboBox search that ignores diacritics -


i have application people can enter names of places in form. being europe, have deal names includes diacritics orléans, köln, liège, châteauroux. when people enter names want them able type characters without diacritics still come list of names include them can select accented name. program has long non-exhaustive list of names (people can enter name like).

i have function finds names based on non-diacritic match. 'orle' return 'orléans', 'kol' finds 'köln', etc.

i tried 2 things:

1: qlineedit qcompleter fills list in completer matches using qstringlistmodel. unfortunately not work since list contain accented version of name, not match value entered user, qlineedit not show name in popup (if @ all).

i played qabstractitemmodel until realized qcompleter string match on data returned model, again 'orle' != 'orlé'.

2: editable qcombobox list gets filled dynamically depending on text has been entered far. following code connected()ed qcombobox::edittextchanged(qstring):

void tripformcargohelper::fromedited (const qstring &str) {   if (str.length () >= 3)   {     qstringlist flist = m_database->findlocationstrings (str);     flist.push_front (str); // add text we're editing first     bool b = box->blocksignals (true); // prevent recursive signals     box->clear ();     box->additems (flist);     box->blocksignals (b);     box->showpopup ();   }   else   {     box->clear ();     box->hidepopup ();   } 

}

this works, half... want popup appear when characters have been entered [1] removes focus line-edit. clicking line-edit closes popup, end catch-22 (people should able continue typing characters, narrowing search).

any suggestions on how make work appreciated. prefer solution qlineedit. version qt 5.4.

[1] should when find matches, alas.

this should work:

go qcompleter solution.
create class inherits qcompleter , re-implement qcompleter::splitpath:

diacriticfreecompleter::diacriticfreecompleter(qobject *parent)     : qcompleter(parent) { }  qstringlist diacriticfreecompleter::splitpath(const qstring &path) const {     return qstringlist() << clearedfromdiacritic(path); }  qstring diacriticfreecompleter::pathfromindex(const qmodelindex &index) const {     // needed use original value when value selected     return index.data().tostring(); } 

now crate data model contains cities (words diacritics) , under custom role number return string diacritics free (sub-classing qstringlistmodel easiest way, re implement data specially treat role value):

diactricfreestringlistmodel::diactricfreestringlistmodel(qobject *parent)     : qstringlistmodel(parent) {     setdiactricfreerole(qt::userrole+10); }  qvariant diactricfreestringlistmodel::data(const qmodelindex &index, int role) const {     if (role==diactricfreerole()) {         qstring value = qstringlistmodel::data(index, qt::displayrole).tostring();         return clearedfromdiacritic(value);     } else {         return qstringlistmodel::data(index, role);     } }  void diactricfreestringlistmodel::setdiactricfreerole(int role) {     mdiactricfreerole = role; }  int diactricfreestringlistmodel::diactricfreerole() const {     return mdiactricfreerole; } 

now connect model qcompleter set special role value completionrole , should work perfectly.

mainwindow::mainwindow(qwidget *parent) :     qmainwindow(parent),     ui(new ui::mainwindow) {     ui->setupui(this);     diacriticfreecompleter *completer = new diacriticfreecompleter(this);     diactricfreestringlistmodel *model = new diactricfreestringlistmodel(this);     completer->setmodel(model);     completer->setcompletionrole(model->diactricfreerole());     model->setstringlist(qstringlist()                          << "kraków"                          << "Łba"                          << "Żarów"                          << "Źródło"                          << "Łęg"                          << "london"                          << "münchen"                          << "orléans"                          << "köln"                          << "liège"                          << "châteauroux");     ui->lineedit->setcompleter(completer); } 

i've tested works perfectly. note in practice i've pasted here complete code (just omitted obvious things), solution quite simple.


Comments

Popular posts from this blog

c# - Better 64-bit byte array hash -

webrtc - Which ICE candidate am I using and why? -

php - Zend Framework / Skeleton-Application / Composer install issue -