Changing multiple selection mode for QListView - qt

In QListView, i'd like to disable mouse drag multiple selection - that is, mous down on a row, drag the mouse down and select the rows below it while dragging.
I'd still like row selection using CTRL-mouse click.
Is that possible?

It seems you've set the list view's selection mode to QAbstractItemView::MultiSelection. Try setting it to QAbstractItemView::ExtendedSelection with:
listView->setSelectionMode( QAbstractItemView::ExtendedSelection );
and see if that helps.

I think the easiest way to do it would be to create a derived class from the QListView and then override its mouseMoveEvent function. This function in the Qt Code for the QListView looks for a dragging state and creates a rectangle. I think something like this may work, but I didn't test it:
void DerivedListView::mouseMoveEvent(QMouseEvent *e) {
if (state() != DragSelectingState)
QListView::mouseMoveEvent(e);
}

Related

Multiple Selection table, without selection of mouse dragging

I would like to have QAbstractItemView that will allow multi-selection of items only with ctrl button toggle. I can't use QAbstractItemView::ExtandedSelection because it also allow multiple items selection by dragging the mouse over them.
I assume you are using a QTableView
You can override the QTableView and then use mouseMoveEvent cleverly to ensure that user can't make multiple selections by dragging!
If user enters into mouseMoveEvent with the left mouse button pressed, you can choose to eat the event without passing it to the QTableView that will remove the possibility of multiple selection.
e.g.
void
TableView::mouseMoveEvent( QMouseEvent * inEvent )
{
// Deliberately commented to not to pass this event to parent to avoid multiple selection
// QTableView( inEvent );
inEvent->accept();
}
This might work for you, you may also have to be careful in the mouseMoveEvent, when you do above to mousePressEvent you have to do the same for mouseReleaseEvent as well.
Though this is just a theory , but is should work!

How to stop a middle mouse click from deselecting items in a QGraphicsScene without blocking it from items in the scene?

I am creating a node graph and I want to be able to click the empty space in a scene and middle-mouse-drag to navigate without deselecting the currently selected items in the scene. Any suggestions?
I can block the middle click in the view's mousePressEvent and get the right behavior but then I no longer have middle-mouse click events working on items in the scene. I don't mind a middle-click resulting in a single selection when clicking on an item in the scene, but if I middle-click the empty space in the scene I don't want the selection altered.
This didn't cover the more complex behavior I am looking for: PyQt. How to block clear selection on mouse right click?
I didn't try using an eventFilter as I assume the issue would be the same
I am using PyQt/PySide, FWIW.
Before I roll my own workaround I thought I'd post here for the correct way or at least other workaround ideas.
Some workaround ideas:
Block the mousePressEvent to the scene but iterate over child items to deliver it directly
Restore selection while still in the mousePressEvent in the scene. Probably bad for performance at scale but simple I suppose.
Any feedback would be great!
[Edit:]
Here is my python version of the answer. Code tested. In my QGraphicsScene derived class:
def mousePressEvent(self, event):
# Prevent the QGraphicsScene default behavior to deselect-all when clicking on
# empty space by blocking the event in this circumstance.
item_under_the_mouse = self.itemAt(event.scenePos())
if event.button() == QtCore.Qt.MidButton and not item_under_the_mouse:
event.accept()
else:
super(GraphScene, self).mousePressEvent(event)
In your QGraphicsScene::mousePressEvent derived implementation, if it's a middle mouse click, check for items under the mouse click. If there aren't any, then accept the event and don't call the base class implementation. If something is under the click, then just call the base implementation; you don't have to try to reimplement that yourself. I think this is the general idea:
void MyScene::mousePressEvent (QGraphicsSceneMouseEvent *evt)
{
if ((evt->buttons () & Qt::MidButton) && items (evt->scenePos ().count ())
{
QGraphicsScene::mousePressEvent (evt);
}
else
{
evt->accept ();
}
}
I'm not sure if the accept is required in this case or not. I haven't compiled or tested this, but hopefully, it's helpful to get you going in the right direction.

QCompleter popup position

I'm having trouble trying to move the QCompleter popup view position.
I tried the QCompeter:complete and it's pops the completer view in the position as I wanted.
But if I start typing it close it, and open the completer in the 'default' position.
I also tried the QCompleter:setPopup() function.
I create a QListView and I tried to moved to different position.
And still the QCompleter popup view remains in the same position.
In my project I'm using a QFrame that wrap QLineEdit.
And I want that the completer view will get the QFrame position.
I succeed to set the completer view width via setFixedWidth() function.
but not to move the position.
Any suggestions ?
Thanks.
I suggest setting the CompletionMode to InlineCompletion, so there will be no popup. Then make your QListView indepedant of the QLineEdit; just react to signals that indicate when a view types some text, leaves the QLineEdit, etc (hint: subclass QListView) and sets the text in QLineEdit when a user selects a value from the list.
I think it will be difficult to override the placement since QCompleter takes ownership of your QListView. (Personally I think it does not make much sense to place the completion list somewhere else than next to the input field, but alas...)

How to add unselectable instruction text to the QComboBox

I have a QComboBox with the items.
I want to put some instruction as top item in my combo box such as "Select number..". It shouldn't be selected too.
is there anyway to do it in QComboBox widget?
Thanks for reading.
You can initially put an instruction item as a regular item and remove it from the combo box when it is clicked at the first time. This signal signal
should do the job
void highlighted(int index);
You can make the item unselectable via the list model. Something like:
comboBox->model()->itemData(0)->setEnabled(false)
But you might need a cast in there, not sure: I use PySide so I don't :-)

I want to extend dropEvent() (QListWidget), should I completely reimplement it?

I have a QListWidget and I have set it to accept drops, the mode to be DragDrop etc and I can move QListWidgetItems all around the place (inside the QListWidget of course).
I like this behavior and I want it to let it as is, but I also want my QListWidget to accept drops from a QTreeWidget as well. If I attempt to reimplement the dropEvent() of my QListWidget then I lose the default behavior.
Is there any way to just extend the current behavior so as to have both drag-drop between listwidget items and drag-drop from the treewidget to the listwidget or I have to completely re-write both behaviors in my dropEvent() reimplementation?
Thanks a lot for any answers :)
Two ways:
implement a standalone event filter and make it act upon QEvent::Drop. Install it on your original QListWidget. Return false so that the original dropEvent() handler is called afterwards.
inherit from QListWidget, reimplement dropEvent(evt) and as a last statement, call QListWidget::dropEvent(evt);. Your original behavior will be retained.
No.
Subclass QListWidget, reimplement
virtual void QListWidget::dropEvent ( QDropEvent * event )
and explicitly call
QListWidget::dropEvent(event);
whenever you need the default behavior.
How to call a parent class function from derived class function?

Resources