I have QTableView which has QComboBox in one of the columns. The combobox is displaying data from a vector which get updates when I click a button.
When I start the application the combobox displays all the items in vector. Now I press the button (which adds more items to the vector) but the combobox doesn't reflect new data in vector. It still shows old data. I am also emitting dataChanged() once the vector is updated but I don't see any change. data() function does get call in the model which does return all the elements of the vector, but setEditorData doesn't get call in delegate.
Am I missing something.
Thanks,
Dev
Then you need to do something like this function:
void updateComboBox(QComboBox *comboToUpdate, const QStringList & list )
{
QString curentText = comboToUpdate->currntText();
comboToUpdate->clear();
comboToUpdate->insertItems(list);
comboToUpdate->setCurrentIndex(comboToUpdate->findText(currentText));
}
Lines
QString currentText = comboToUpdate->currentText();
...
comboToUpdate->setCurrentIndex(comboToUpdate->findText(currentText));
are optional and used to don't change currentItem after selection.
Related
I am making a qt application with PyQt. I have a custom QTableModel that i show in a QTableView. Each row in this model can be checked, when a row is checked I want it to appear in another QTableView. To do this I made a custom proxymodel subclassing from QSortFilterProxyModel.
In my custom model I reimplemented the filterAcceptsRow method to only accept rows that are checked:
def filterAcceptsRow(self, pos, index):
model = self.sourceModel() # The sourcemodel is a 2d array of QStandardItem
row = model.row(pos) # This method returns the row at index pos
if row[0].checkState(): # The first QStandardItem has a checkbox
return True
return False
This works once at the start of my program (I assume when i call setSourceModel) but doesn't update when the checked items change. How do I make sure this function gets called when the checkstate changes in my base model? Or is there another way to do this?
I created TableView (by inhereting from QTableView) and Model (by inhereting from QAbstractTableModel) and implemented all their functions that I needed, but now I have to add strange feature - those objects (stored in models) have to be able to cause table view to select "their" row.
It comes from the fact that there is always graphic object related to them and whenever I click on a scene on a certain object, I wish to center on its representation in table view. Can I do this?
You model could implement a signal emitted every time you want to change the selection. Something like this:
void CMyModel::sigUpdateSelection(const QItemSelection & selection, QItemSelectionModel::SelectionFlags flags);
And than you could connect this signal to the QItemSelectionModel of your table view. This is how you get the selection model:
QTableView* view = new QTableView(parent);
QItemSelectionModel* selectionModel = view->selectionModel();
QItemSelectionModel has a slot select(). This is where you will connect your signal.
And this is how you will emit:
// Add to current selection
emit sigUpdateSelection(QItemSelection(indexLeft, indexRight), QItemSelectionModel::Select);
// Clear current selection and select new one
emit sigUpdateSelection(QItemSelection(indexLeft, indexRight), QItemSelectionModel::ClearAndSelect);
There is a QCompleter (set to QLineEdit) populated with QStandardItemModel. That model also populates the QTableView, I need to get the QModelIndex and select it in QTableView but it fails, it
passes text instead of QModelIndex:
completer.highlighted.connect(print_index)
passes only the first index:
completer.highlighted.connect(lambda : select_index(completer.currentIndex()))
def select_index(index):
table_view.setCurrentIndex(index)
I read docs, but cannot understand what do I do wrong.
http://doc.qt.io/qt-5/qcompleter.html#highlighted-1
There's two versions of the highlighted signal: the default one emits a string, the other emits a QModelIndex
To get the index, use:
completer.highlighted[QtCore.QModelIndex].connect(onHighlight)
But be careful, this is the index in the completion model, not the model you populated the completer with. You can use mapToSource to get the original index.
def onHighLight(index):
#completer model
print(index)
#model
sourceIndex=completer.completionModel().mapToSource(index)
print(sourceIndex)
I would like to use row() function of QmodelIndex. It will directly return the list index of your current selection.
QComboBox keeps storing duplicate strings entered by the user, even if I call its member function QComboBox::setDuplicatesEnabled(false).
How can I store single copies of the strings even when the user inserts duplicates?
From Qt documentation:
duplicatesEnabled : bool
This property holds whether the user can enter duplicate items into the combobox.
Note that it is always possible to programmatically insert duplicate items into the combobox.
By default, this property is false (duplicates are not allowed).
Access functions:
bool duplicatesEnabled () const
void setDuplicatesEnabled ( bool enable )
As the documentation says:
This property holds whether the user can enter duplicate items into
the combobox. Note that it is always possible to programmatically
insert duplicate items into the combobox.
So this option doesn't affect string you set programmatically. You need to remove duplicates from your list manually.
For example, if you're storing your list in QStringList, duplicates can be easily removed using list = list.toSet().toList().
you need to check, if the userinput is valid (not duplicated or not) and catch the void editTextChanged ( const QString & text ) signal.
you could also derive your own class from QComboBox and overload the void keyPressEvent(QKeyEvent* event) // may be not the correct name
I have a Qt Form that contains 2 combo box messages. The second combobox message depends on the first combo box message. I mean that the dates from the second combobox message depends on the element that I select in the first combobox.
In this moment I have different dates in the first combobox. But the second combobox is not working. I need to creare a connect method or what?
Thx! APpreciate!
Could someone give me a short example?
It's fairly simple. A combobox emits the currentIndexChanged signal that also tells you the new index. Write a method that accepts an integer and changes the second combobox according to the integer (which is the index of the selection in combobox 1).
Here are some code sniplets from a working example.
Method declaration in your window/whatever class header:
public slots:
void setI1(int index);
Filling combobox 1, connecting the signal, e.g. in the constructor:
i1Box->addItem("Neutral", 0);
i1Box->addItem("2,856 K (Illuminant A, light bulb)", 2856);
// ...
connect(i1Box, SIGNAL(currentIndexChanged(int)),
this, SLOT(setI1(int)));
Implementation of the method:
void ViewerWindow::setI1(int index) {
// either use index directly, or, as in this case we have items holding an int:
int i1 = i1Box->itemData(index).value<int>();
// use the value to change second combobox here
}
If it does not work as expected, it is always helpful to print some debug output inside the method that should be called to see where it goes wrong in the chain.
Reference: http://doc.qt.nokia.com/latest/signalsandslots.html