PDA

View Full Version : QTableWidget, QThread, signals and slots



kazek3018
30th December 2008, 15:36
Hello again.

I working with QTableWidget. After setRowCount() and setColumnCount(), I have to do setItem(i, j, new QTableWidgetItem()). It's clear to me, obviously when I add some rows (or columns) I have to add more QTableWidgetItem. My question is do I have to remove QTableWidgetItem in this way

QTableWidgetItem *tmp;
tmp=m_ui->TableWidget->takeItem(i, j);
delete tmp;

before I set row count to smaller number? Or its implemented inside setRowCount()?

And second thing, I have to change GUI from QThread (display progress information in log window). For this I use signals and slots coonect looks like:

connect(......., Qt::DirectConnection);
I use DirectConnection because it's very important to keep the same order in signal processing and emitting. It's works but sometime I get:

QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
in application output window, why?

jpn
30th December 2008, 16:11
Do NOT touch GUI in a worker thread.


Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread.

I'm afraid you have to re-think the design.

kazek3018
30th December 2008, 17:47
I'm not touching GUI from thread.


Answer=Interface->Read();
if (Answer!=NULL)
{
char* tmp;
tmp=new char[Answer->Len*2+1];
convertByteTabToStr(Answer->Data, tmp, Answer->Len);
emit setTextQLineEdit(m_ui->AnsLineEdit, tmp);
emit appendQTextEdit(m_ui->LogTextEdit, QString("Ans --> ") +tmp);
delete[] tmp;
delete[] Answer->Data;
delete Answer;
}
else
{
emit setTextQLineEdit(m_ui->AnsLineEdit, "");
emit appendQTextEdit(m_ui->LogTextEdit, "Ans --> Can't read Ans.");
char Text[]="Can't read Ans.";
emit showMessageBox(Text, NULL, QMessageBox::Critical);
}

I'm working with external device connected via RS232. I can't determine when the data will be came in, or how long I have to wait for answer (and answer length as well, simple I have to check when the data stop came in). From past I know that second thread is the best way (and the fasted too). Later I have to write another thread to listen on ethernet socket (it will be collect report from far away devices, and check the data). I can write data to file, and read the file in main thread then fill GUI widget, buy users don't like progress bars. They want to see how its going. Alternate method is function onIdle() (function that is calling when event queue is empty) and it's implemented in main thread (but it is not a really good idea). This is the reason why I chose the thread.
What about the first question?

jpn
30th December 2008, 19:12
I'm confused. First of all, emitting a direct signal from a worker thread means that the GUI thread gets called in the worker thread context. Secondly, I presume QTextCursor is pretty much limited to the GUI thread since it deals with QFont, so it's not a registered meta type for a reason.

As for the second question, yes QTableWidget::setRowCount() will cleanup items where appropriate.

kazek3018
30th December 2008, 21:21
As for the second question, yes QTableWidget::setRowCount() will cleanup items where appropriate.

Good, less work for me.

Qt::BlockingQueuedConnection

With this parameter program works fine, I think it's should be keep order.