QCompleter and QListWidget as custom popup issue - qt

I have a QCompleter using a QStringListModel for my QPlainTextEdit (check this example):
QStringListModel* model = new QStringListModel(names);
QCompleter* completer = new QCompleter(model);
completer->setCompletionMode(QCompleter::PopupCompletion);
completer->setModelSorting(QCompleter::UnsortedModel);
It works fine. Now I need some Icon, Tooltips for each suggestion I'm trying to use a QListWidget as custom popup:
QListWidget* w = new QListWidget();
foreach(name, names) {
QListWidgetItem* i = new QListWidgetItem(name);
i->setIcon(/*my Icon*/);
i->setToolTip("");
w->addItem(i);
}
completer->setPopup(w);
The popup ok, just like I need, but the completion no more work. I cannot type the text to make it filter the suggestion, just Up/Down key.
I have try:
completer->setModel(w->model());
but no help!
What is my misstake or just QStringListModel give me the ability to filter the suggestions? What do you suggest?
Thanks you!

I mostly deal with PyQt, but same deal. My syntax may be off, but you should use a QStandardItemModel vs. a QStringListModel. From there, you can leave it as the standard popup (QListView)
Something like:
QStandardItemModel* model = new QStandardItemModel();
// initialize the model
int rows = names.count(); // assuming this is a QStringList
model->setRowCount(rows);
model->setColumnCount(1);
// load the items
int row = 0;
foreach(name, names) {
QStandardItem* item = new QStandardItem(name);
item->setIcon(QIcon(":some/icon.png");
item->setToolTip("some tool tip");
model->setItem(row, 0, item);
row++;
}
completer->setModel(model);
completer->popup()->setModel(model); // may or may not be needed

Related

Qt - Dynamically create, read from and destroy widgets (QLineEdit)

I have the following situation:
I have QSpinBox where the user of my application can select how many instances of an item he wants to create. In a next step, he has to designate a name for each item. I wanted to solve this problem by dynamically creating a number of QLabels and QLineEdits corresponding to the number the user selected in the SpinBox. So, when the number is rising, I want to add new LineEdits, when the number falls, I want to remove the now obsolete LineEdits.
Well, guess what - this turns out much more difficult than I expected. I've searched the web, but the results were more than disappointing. There seems to be no easy way to dynamically create, maintain (maybe in a list?) and destroy those widgets. Can anybody point me in the right direction how to do this?
Take a while and check QListWidget, it does what you exactly want for you by using QListWidgetItem.
An little example: this function adds a new element to a QListWidgetwith a defined QWidget as view and return the current index:
QModelIndex MainWindow::addNewItem(QWidget* widget) {
QListWidgetItem* item = new QListWidgetItem;
ui->listWidget->addItem(item1);
ui->listWidget->setItemWidget(item, widget);
return ui->listWidget->indexFromItem(item);
}
Now, if your user selects X items, you should iterate to create X widgets and you could save all the widgets in a QList:
listWidget.clear();
for (int i=0; i<X; i++) {
QTextEdit* edit = new QTextEdit();
const QModelIndex& index = addNetItem(edit);
qDebug() << "New element: " << index;
listWidget.append(edit);
// Handle edit text event
connect(edit, SIGNAL(textChanged()), this, SLOT(yourCustomHandler()));
}
Now, just show the list with all the edit fields.

Set selected item for QComboBox

I have a simple QComboBox widget, which has 2 values inside: True and False.
And I have a QString variable currValue, which is one of those values. I want to set my widget's current value with currValue.
I thought that solution is the following:
first lets initialize currValue;
QString currValue = "False";
QComboBox* combo = new QComboBox();
combo->addItem("True");
combo->addItem("False");
combo->setCurrentIndex(combo->findData(currValue));
But it doesn't work.
Am I doing something wrong ?
And Why QComboBox has no member setCurrentItem() or smth like that ?
You actually need to write it in the following way:
QComboBox* combo = new QComboBox();
combo->addItem("True", "True");
combo->addItem("False", "False");
combo->setCurrentIndex(combo->findData("False"));
The problem in your implementation was that you did not set the items' userData, but only text. In the same time you tried to find item by its userData which was empty.
With the given implementation, I just use the second argument of QComboBox::addItem(const QString &text, const QVariant &userData = QVariant())) function that sets the item's userData (QVariant).
UPDATE:
The alternative way to find the combo box item is setting the specific role as the second argument for QComboBox::findData() function. If you don't want to explicitly set the user data, you can refer to the items texts with Qt::DisplayRole flag, i.e.:
QComboBox* combo = new QComboBox();
combo->addItem("True");
combo->addItem("False");
combo->setCurrentIndex(combo->findData("False", Qt::DisplayRole)); // <- refers to the item text
UPDATE 2:
Another alternative could be using text based lookup function QComboBox::findText():
QComboBox* combo = new QComboBox();
combo->addItem("True");
combo->addItem("False");
combo->setCurrentIndex(combo->findText("False"));
I have got answer to my own question.
combo->setCurrentIndex(combo->findText(currValue));

Qt QTabWidget - auto set tab name number

I working on one application and I have problem with tab name.
When I click on push button (NEW) I want to dynamically create new tab.
With this function i create new file:
bool MainWindow::toolbarNewFile()
{
QWidget *page = new QWidget;
QTextEdit *codeEditor = new QTextEdit;
QGridLayout *layout = new QGridLayout;
layout->addWidget(codeEditor);
page->setLayout(layout);
tab_widget->addTab(page,"File");
return true;
}
But all tabs have name "FILE"
How to set in tab name number. When i make new tab auto set number of the tab like this.
File-1, File-2, File-3
I try to set counter i=0; and in addTab(page,"File-"+ i++); Doesn't work.
You need to covert integer to the QString to be able to concat it to the QString. Even better, you can use QString::arg function and get readable and potentially faster code very easily:
tab_widget->addTab(page, QString("File-%1").arg(i++));
Where i is field in your class initialized to 1.

Checking then Adding items to QCompleter model

I am currently working on a code editor written in Qt,
I have managed to implement most of the features which I desire, i.e. auto completion and syntax highlighting but there is one problem which I can't figure out.
I have created a model for which the QCompleter uses, which is fine for things like html tags and c++ keywords such as if else etc.
But I would like to add variables to the completer as they are entered by the user.
So I created an event on the QTextEdit which will get the word (I know I need to check to make sure that it is a variable etc but I just want to get it working for now).
void TextEdit::checkWord()
{
//going to get the previous word and try to do something with it
QTextCursor tc = textCursor();
tc.movePosition(QTextCursor::PreviousWord);
tc.select(QTextCursor::WordUnderCursor);
QString word = tc.selectedText();
//check to see it is in the model
}
But now I want to work out how to check to see if that word is already in the QCompleters model and if it isn't how do I add it?
I have tried the following:
QAbstractItemModel *m = completer->model();
//dont know what to do with it now :(
You can check if word is in your QCompleter really by using
QAbstractItemModel *m = completer->model();
as you can see, method model() returns const pointer.
That is good for checking procedure, you can check like this:
bool matched = false;
QString etalon("second");
QStringListModel *strModel = qobject_cast<QStringListModel*>(completer.model());
if (strModel!=NULL)
foreach (QString str, strModel->stringList()) {
if (str == etalon)
{
matched = true;
break;
}
}
qDebug()<<matched;
But for your purposes, I recommend you to declare QStringListModel, and connect it to your completer, and then, all of operations you'll must do thru your model, according to Qt's principles of MVC programming (http://doc.qt.digia.com/qt/model-view-programming.html).
Your code can be like this:
// declaration
QCompleter completer;
QStringListModel completerModel;
// initialization
completer.setModel(&completerModel);
QStringList stringListForCompleter;
stringListForCompleter << "first" << "second" << "third";
completerModel.setStringList(stringListForCompleter);
// adding new word to your completer list
completerModel.setStringList(completerModel.stringList() << "New Word");
Good luck!

Problem in inserting element to listview in QT

HI..
i want to add elements dynamically to listview in QT for symbian OS, i have set of delegate methods associated with listview.
if i add elements statically, the control comes to delegate methods, and view is perfect.
but if i add dynamically, control is not at all coming to delegate methods.
i don't no how to do it. ill place here some sample code, that how i am adding elements.
this is how i am setting the view,
MylistView = new QListView();
QDesktopWidget* desktopWidget = QApplication::desktop();
QRect clientRect = desktopWidget->geometry();
MylistView->setMinimumSize(QSize(clientRect.width()-7,clientRect.height()-1));
MylistView->setViewMode(QListView::ListMode);
MylistView->setMovement(QListView::Free);
MylistView->setItemDelegate(new ItemDeligate(MylistView));
MylistView->setSelectionMode(QAbstractItemView::SingleSelection);
bool val =GreenPixmap.load(":/new/prefix1/temp/test.png");
ListModel = new QStandardItemModel();
ListModel->appendColumn(ItemList);
MylistView->setModel(ListModel);
Listlayout.addWidget(MylistView);
Listlayout.addWidget(MylistView);
this->setLayout(&Listlayout);
AddItemMenu = new QAction("Add",this);
menuBar()->addAction(AddItemMenu);
val = connect(AddItemMenu,SIGNAL(triggered()),this,SLOT(addItem()));
This is how i am adding dynamically when the click event occurs, (i.e dynamically adding items)
QStandardItem *Items = new QStandardItem(QIcon(GreenPixmap),"Avatar");
Items->setData("WAKE UP",ItemDeligate::SubTextRole);
ItemList.append(Items);
ListModel->appendColumn(ItemList);
please suggest me, what mistake i am doing in adding elemetns
I just made this quick example in my app, it's working, maybe it will gibe you an hint :
QStandardItem* Items = new QStandardItem("Avatar");
QStandardItemModel* ListModel = new QStandardItemModel();
ListModel->appendRow(Items);
listView->setModel(ListModel);
In summary, you should simply append a row on your model ! It should fix your problem !
If I missed something, let me know !

Resources