Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Multiple AutoCompleters for the same LineEdit box



  • Hello all,

    I have a Line Edit box and a Combo Box in my program. My program searches a DB using the info found in the aforementioned boxes. The Lined Edit box is the search term and the Combo box is the filter to search by.
    e.g. the Combo box contains search filters Turtle, Rabbit, Dog, Cat
    If I select Turtle in the combo box, and type "Box" in the Line Edit my program will return all the info the DB has on Box Turtles.

    I would like to have an autocomplete available with previous search terms. I don't want Cat, Dog, and Turtle Search terms in the same list. What I would like to accomplish is, the state of the combo box determines what AutoComplete is currently working on the Line Edit.

    What i have tried so far is create a slot for the combo box with signal currentIndexChanged(int)
    I have created 4 QCompleter's *TurtleCompleter, *RabbitCompleter, ..etc.
    Data is pulled in for my recent 5 searches for each of my four filters and stored in a model.
    I iterate over that model and store the last 5 search terms in a QStringList for each filter, TurtleList, RabbitList, DogList, CatList.
    After that a new Qcompleter is made called TurtleCompleter, RabbitCompleter, DogCompleter, CatCompleter.
    by default i assign the TurtleCompleter to the LineEdit via:
    ui->lineEdit->setCompleter(TurtleCompleter);
    As a test i hard coded a change the completer in the comboBox slot via
    ui->lineEdit->setCompleter(RabbitCompleter);
    My program crashes when first fired up. The bombo box slot code is being executed when the program is launched. I guess becuase the program detects the default combo box filter as a change when the program starts.
    If I comment out the ui->lineEdit->setCompleter(RabbitCompleter); the program runs fine but without the autocompleter changing to match the filter selected in the combo box.

    Any Help would be greatly appreciated.


  • Lifetime Qt Champion

    Hi
    If you dont find the actual cuase of the crash, you could
    use https://doc.qt.io/qt-5/qsignalblocker.html
    during startup.


  • Lifetime Qt Champion

    Hi,

    Might be a silly question but are you sure your completer is valid when you set it on application startup ?



  • @SGaist

    In the animalsearch.h file i have the following:

    namespace Ui {
    class AnimalSearch;
    }
    class AnimalSearch : public QDialog 
    {
         Q_OBJECT
    public:
       stuff
    
    private slots:
        stuff
    
    signals: 
        stuff
    
    private:
        QCompleter *TurtleCompleter;
        QCompleter *RabbitCompleter;
        QCompleter *DogCompleter;
        QCompleter *CatCompleter;
    
    };
    

    In the animalsearch.cpp i have the following:

    #includes section
    
    AnimalSearch::AnimalSearch(QWidget *parent):
        QDialog(parent),
        ui(new Ui::AnimalSearch)
    {
        QStringList animals << "Turtle" << "Rabbit" << "Dog" << "Cat";
        ui->cmbFilter->addItems(animals);
    
        //section that collects the past animal search and stores in a model.  
        //Then I parse the data out of the model into individual QStringLists: 
       TurtleList, RabbitList, DogList, CatList;
    
        //Display each string list to make certain it is good. (the data looks good when i run.)
        qDebug() << TurtleList;
        qDebug() << RabbitList;
        qDebug() << DogList;
        qDebug() << CatList;
    
        //Then I build the completers
        TurtleCompleter = new QCompleter(TurtleList, this);
        ui->lineBy->setCompleter(TurtleList); //Default Completer
    
        RabbitCompleter = new QCompleter(RabbitList, this);
    
        DogCompleter = new QCompleter(DogList, this);
    
        CatCompleter = new QCompleter(CatList, this);
    }
    
    //Section about cmbFilter selection
    void AnimalSearch::on_cmbFilter_currentIndexChanged()
    {
        //for a test just neglect the current index and try to change the qcompleter being used by the lineBy box.
        qDebug() << "Does this print?";
        ui->lineBy->setCompleter(RabbitCompleter);
    }
    

    When the program is run it crashes after the qDebug() << "Does this print?"


  • Lifetime Qt Champion

    Hi
    where is your setupUI() ?



  • @mrjj

    The animalsearch ui is launched when a button is clicked on the parent ui. Does that answer the question? I'm not a seasoned Qt user so I may have not understood your question. Thanks for your time.


  • Lifetime Qt Champion

    Hi
    sorry if not clear.
    Normally when using UI files, there is a call to a function that creates the objects.
    MainWindow::MainWindow(QWidget* parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow) {
    ui->setupUi(this); <<<< --- std.

    I could not see in your code so i did wonder. but if it runs it must be there :)



  • @mrjj
    Ok yeah i see that in the mainview.cpp which launches the animalsearch ui. It's exactly as you posted.


  • Lifetime Qt Champion

    @Core2
    Ok, but i assume you have the same for AnimalSearch or else anything you have in the UI files
    will be dangling pointers.

    You call setupUI manually from mainwindow or something like that ?

    Can you show how you init AnimalSearch ?
    if you never call setup, the line ui->cmbFilter->xxx would crash
    so since it seems something else, i guess its ok, just not standard way?



  • @mrjj

    from mainview.cpp

    //Needs better commenting.
    void MainView::on_btnAnimalSearch_clicked()
    {
        AnimalSearch animalsearch;
        animalsearch.setModal(true);
        connect(&animalsearch, SIGNAL(sendData(QString)), this, SLOT(printData(QString)));
        animalsearch.exec();
    }
    

  • Lifetime Qt Champion

    @Core2
    ok. odd. but dialog works and the widgets in the UI are shown so
    that part does work?
    I mean, there is no issues with
    ui->cmbFilter->addItems(animals); ?
    That would really crash if dangling pointer.



  • @mrjj

    yeah that part works and has been for some time. now that i introduced multiple Qcompleters and trying to assign a Qcompleter depending on cmbFilter state is when things started failing. As you can see from the example code above I assign a default of TurtleQcompleter, and then in the section of code:

    void AnimalSearch::on_cmbFilter_currentIndexChanged()
    

    runs when the animalsearch ui is started, even though I don't change the cmbFilter, and I try for a test to set the Qcompleter to Rabbit Qcompleter from the earlier assignment of TurtleQcompleter.


  • Lifetime Qt Champion

    Hi
    yes it will fire such signal when current item/index is set.
    Also when done in code as doc states
    http://doc.qt.io/qt-5/qcombobox.html#currentIndexChanged
    So that is pretty normal.



  • @mrjj

    Ok good to know. I will remove my line where I assign a default Qcompleter, and allow this section of code to make the first assignment.

    Now i just have to figure out after I make the Qcompleters why i can't assign a different Qcompleter from elsewhere in the code.

    Thanks again for your time.


  • Lifetime Qt Champion

    Can you show the backtrace from your crash ?



  • @SGaist

    backtrace? I don't know what that is.


  • Lifetime Qt Champion

    It's the list of functions called shown by the debugger when the application crashes.


  • Lifetime Qt Champion

    Hi
    What you mean by
    "why i can't assign a different Qcompleter from elsewhere in the code" ?
    In what why does it not work ?



  • @SGaist

    I think by watching this video by VoidRealms I will be able to gather this info.
    https://www.youtube.com/watch?v=B7UsWtyhXh4



  • @mrjj

    I mean that in the animalsearch ui(new Ui::AnimalSearch) I create the Qcompleters from data i collect from sql into a model that i parse to QstringLists, then in a cmbFilter slot I assign the Qcompleter to the lineBy box.


  • Lifetime Qt Champion

    @Core2
    Ok. that should just work.
    I tried the Qt completer sample and there seems to be no issues switching completer.



  • @mrjj

    Interesting. I may set up a test project where i set up a basic program to do this one thing with a cmbFilter, and a LineEdit. Until then I think I go the debugger working and am getting good info. I'm about to respond to SGaist.


  • Lifetime Qt Champion

    @Core2
    Ok. good plan. The call stack will show what happened up till the crash.
    alt text



  • @Core2

    In the issues window: "c:\blahblahblah\qt\qtbase\src\corelib\tools\qscopedpointer.h:140: error: Debugger encountered an exception: Exception at 0x7747379a, code: 0xc0000005: read access violation at: 0x0, flags=0x0 (first chance)

    In the Debugger Window: There is 76 Levels, and there is a yellow arrow pointing to the level 11, AnimalSearch::on_cmbFilter_currentIndexChanged.
    The file column of that row contains this animalsearch.cpp
    The line row contains 300, which is the line just after the line ui->lineBy->setCompleter(RabbitCompleter);

    Looking at the top right window after i click on the level 11, I can see what variables are in memory and what the value and types are (Too freaking cool!)

    Is the information i listed above the backtrace?


  • Lifetime Qt Champion

    Hi
    I would check the values of all UI widgets (if non null)
    and i would also
    change so .h says
    QCompleter *TurtleCompleter=0;
    QCompleter *RabbitCompleter=0;
    QCompleter *DogCompleter=0;
    QCompleter *CatCompleter=0;

    so im sure they are allocated when i reach crash point ( as in not null)

    The error code: 0xc0000005: + 0x0, suggests a null pointer.



  • @mrjj

    Thank you both for taking the time to help me through this. Setting the pointers to 0 first fixed the issue!

    I have now added code that looks at the index value of cmbFilter and changes the Qcompleter being used on the lineBy box. Good stuff!

    Have a good day!


Log in to reply