PDA

View Full Version : Is it possible to cast QTableWidgetItem ti QLineEdit



SIFE
13th December 2011, 00:59
I have QTableWidget, and in the second column I want to provide to user a completer feature, how ever, to accomplish this, I attached a QLineEdit to the specified column. Now I am facing a new problem, since my QTableWidget has to be auto grown(when ever user type a character in the widget , a new row inserted to QTableWidget), so, after reading documentation, I found itemChanged(QTableWidgetItem*) SIGNAL may help me.
SO, when ever a user type some thing in the item(say column 2, row 0), I catch the item changed, cast it to QLineEdit, set completer to it, user will be able to see suggestion, a new row inserted.


connect(ui->billTableWidget, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(addRow(QTableWidgetItem*)));

Store::addRow(QTableWidgetItem*)
{
QLineEdit *itemEdit = new QLineEdit;
itemEdit = dynamic_cast<QLineEdit*>(item);
Clients client(ui);
QStringList clients = client.getClients();
completer = new QCompleter(clients, itemEdit);
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setCompletionMode(QCompleter::PopupCompletion);
itemEdit->setCompleter(completer);
}
But this unfrountly cause the application to be exited on signal 11 (core dumped) like the console said. Is there some thing missing?

ChrisW67
13th December 2011, 01:17
A QTableWidgetItem is a data object not a widget. You cannot cast from one to the other. Your code crashes because itemEdit at line 6 will be NULL.

If you need access to customise the widget used when a cell is edited you should create and attach a QStyledItemDelegate

d_stranz
13th December 2011, 03:31
Not only that, but in line 4 why do you create a new QLineEdit, assign the pointer to "itemEdit", then immediately throw it away by trying to assign another value to the pointer in line 5?

ChrisW67
13th December 2011, 03:47
The whole premise of the question is a little strange anyway. There will not be an item at row 2 column 0 to edit unless there is already a row 2 in the widget's model, yet SIFE it talking about doing this as the row is added or adding a separate row as the user types. It really isn't very clear.

SIFE
13th December 2011, 22:36
I am trying to avoid attaching a QLineEdit to (row = n, col = 2, n refer to the number of row inserted), since QTableWidget provide lineedit, I tried to use in order to attache it with my completer. The problem I am facing now is, if I attached a QLineEdit, I lost the signals of QTableWidget in row = n, col = 2, while other cells still can be notified if change some thing or click on theme, for this reason I am looking for a way to notifier me if the widget in row =n and col=2 changed or not.

ChrisW67
14th December 2011, 01:03
I am trying to avoid attaching a QLineEdit to (row = n, col = 2, n refer to the number of row inserted),
Why?

since QTableWidget provide lineedit, I tried to use in order to attache it with my completer.
Use a QStyleItemDelegate subclass and create your own QLineEdit with a QCompleter attached when the cell is edited. An editing widget does not exist until the user attempts to edit the cell. The editor is created by a default delegate, used, and destroyed when the user presses Enter or leaves the cell. To intercept this and substitute your enhanced editor you need to replace the delegate. The data item is accessed through the underlying model by the delegate to populate the editor and to write the edited value back at the completion of editing.

The problem I am facing now is, if I attached a QLineEdit, I lost the signals of QTableWidget in row = n, col = 2, while other cells still can be notified if change some thing or click on theme,
The problem you are facing with the code above is that you are doing nothing like attaching a completer to the default line edit... your code will only crash the program. The data item associated with a table cell is not a widget and you cannot treat it as one.

for this reason I am looking for a way to notifier me if the widget in row =n and col=2 changed or not.
The QTableWidget::itemChanged() signal tells you when any item in the model changes. The item can tell you which row and column it represents. This is unaffected by changing the delegate.

SIFE
16th December 2011, 10:53
Why?
If attached a QLineEdit in the cell, I lose cell/item signals, because QLineEdit in top of it.
I think I achieved my goal:

Store::Store(QWidget *parent) : QMainWindow(parent),
ui(new Ui::Store)
{
ui->setupUi(this);

Store::setupBill();
....
}


void Store::setupBill()
{
.....

QLineEdit *item = new QLineEdit;
ui->billTableWidget->setCellWidget(0, 1, item);
Items items(ui);
lst = new QStringList(items.getItems());
cmpter = new QCompleter(*lst, item);
cmpter->setCaseSensitivity(Qt::CaseInsensitive);
cmpter->setCompletionMode(QCompleter::PopupCompletion);
item->setCompleter(cmpter);

connect(cmpter, SIGNAL(activated(QString)), this, SLOT(suggestionItems(QString)));
}

First I setup QTableWidget with an attached QLineEdit. Then I connected the activated signal of QCompleter with my SLOT void suggestionItems(QString):

void Store::suggestionItems(QString itm)
{
PrintBill bill(ui);
bill.getItem(itm);
int row = ui->billTableWidget->rowCount();

ui->billTableWidget->insertRow(row);
QTableWidgetItem *itemR = new QTableWidgetItem;
itemR->setText(QString::number(1));
ui->billTableWidget->setItem(row - 1, 3, itemR);
QLineEdit *item = new QLineEdit;
ui->billTableWidget->setCellWidget(row, 1, item);

cmpter->setCaseSensitivity(Qt::CaseInsensitive);
cmpter->setCompletionMode(QCompleter::PopupCompletion);
item->setCompleter(cmpter);
}
Witch my SLOT will fill the empty cells of current row, and then insert a new row attached with QLineEdit and QCompleter.