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

QTreeView focus events and losing selection



  • Hello

    Say I have a programatic function that selects tree items in my view. However when I click back on view, it auto deselects all items and select the one I clicked on to...

    How can I combat this behavior? I tried focusInEvent/set flag to ignore next selection change but I had no luck...

    I'd like to control when click on tree view will cause selection "action" vs when to ignore it as I just want to bring the view to focus so I can execute say... short cut that would scroll to selected items...

    TIA



  • Hi,
    Installing an EventFilter seems to be a solution.
    This is what I'm using to prevent a right click to operate on inactive windows:

    bool Application::eventFilter(QObject *obj, QEvent *event)
    {
    	if(event->type() EQ QEvent::MouseButtonPress)
    		{
    		QMouseEvent* mouseEvent=static_cast<QMouseEvent*>(event);
    		QWidget* win=topLevelAt(mouseEvent->globalPos());
    
    		if(mouseEvent->button() EQ Qt::RightButton)
    			{
    			if( win AND win!=activeWindow())
    				{
    				// empĂȘche de faire un clic droit sur une fenetre non active
    // prevent a right click on non active windows
                    win->activateWindow();
                    win->raise();
    				return true;
    				}
    			}
    ....
    

    In your case, replace Qt::RightButton by Qt::LeftButton
    I'm installing this filter at app level (all top level widgets are concerned)
    I think you can install this filter only for the widgets your treeview is in.



  • @mpergand Interesting thanks! It sounds like a solution. I will give it a go in a few.

    TIA



  • You can subclass QTreeView and override setSelection. Firstly don't forget to set the multiselection mode.

    view->setSelectionMode(QAbstractItemView::MultiSelection);
    

    Override the setSelection method.

    #define MAX_SELECT 3
    void TreeView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
    {
        if(command & QItemSelectionModel::Deselect)
        {
            QTreeView::setSelection(rect,command);
            return;
        }
        if(command & QItemSelectionModel::Clear)
        {
            //Actually purpose this "if branch" to disable clear
            //but MultiSelection mode already do that so execute below command is normal.
            QTreeView::setSelection(rect,command);
            return;
        }
        QModelIndexList  ls = this->selectedIndexes();
        int total = 0;
        for(int i=0; i< ls.size();i++)
        {
            if(ls[i].column() != 0) continue;
            QModelIndex p = ls[i].child(0,0);
            if(!p.isValid())
            {
                //I think when p is invalid ls[i] doesn't have any child. Maybe there is an another way to find this.
                total++;
            }else{
                QString child_data =  p.data().toString();
            }
        }
        if(total < MAX_SELECT )
        {
            QTreeView::setSelection(rect,command);
        }else{
            //You can scroll here.
        }
        return;
    }
    
    

Log in to reply