My QListWidget is not updating when I want
-
Hi,
I have the following trouble with 3 QWidgets communication with each other using signals and slots:
-
Widget # 1 is connected to Widget # 2 (widget # 2 is a thumbnail viewer using QListWidget and QIcon)
-
Widget # 2 is connected to Widget # 3 (widget # 3 is a larger image of the current selected thumbnail)
-
Widget # 1 is an editor where the user can specify 3 coordinates (X,Y,Z) using QLineEdits and the point shall be drawn on each thumbnail in widget # 2.
-
Changes to one of the 3 QLineEdits (X,Y,Z) causes Widget # 1 to emit a signal that Widget # 2 receives.
-
When Widget # 2 receives this signal it shall update the thumbnail viewer instantly (this is NOT OK) and emit a signal to Widget # 3 (this is OK).
-
Widget # 3 shall update the large image with the new point (this is OK)
Widget # 3 is always correctly updated however widget # 2 is not.
The issue is related to the QListWidget used for the thumbnail viewer. It seems that Widget 2 always gets updated if I move from one QLineEdit to another QLineEdit (typically from X parameter to Y parameter). Then the point is updated using the previous sent signal.... Any suggestions?? I am printing to screen every time the signal is received in Widget 2 and it is receiveing the signals all the time. It is only the display that does not update...
I have tried update(), repaint(), QCoreApplication::processEvents() etc.
Why is Widget # 3 always up to date? Widget # 3 uses a QGraphicsView and Pixmap Item to show the image with the point.
Any suggestions?
-
-
Hi,
How are you update your QListWidget ? Can you share the code you are using ?
-
I use the following code to populate the list:
QIcon thumnail = QIcon(Pixmap::fromImage(image));
QListWidgetItem* newItem= new QListWidgetItem(ui_.thumbnailWindow);
// ui_.thumbnailWindow is a QListWidget added in design modenewItem->setText("some text");
newItem->setIcon(thumbnail);The thumbnail viewer (widget #2) is opened by a push button in widget # 1:
using the exec() command....The aim is to update the thumnail viewer (widget # 2) while changing the X,Y,Z coordinates (QLineEdits) in widget # 1. The code for drawing the points on the images (QImages) are not shown in the example code...
-
And what code do you use to refresh the list ?
By the way, why using exec for your dialog ? -
i think you have to implement the event from each QLineEdit (event when textChanged or something like that...) and inside each one event slot, emit your signal OR directly modify the content of the widget 2 (i would prefer use model/view and modify the model datas... but this is not the way you want to go by).
Also, you maybe have to create a pointer for the thumbnail viewer and use a non modal mode with "open()" instead of exec... just for not block the code.
-
Hi,
I have now been able to get it to update. However, it is not a nice solution.
The solution is as follows:
- emit signal...
- change focus between the three line edits
- emit signal again
Then widget # 2 is always updated correctly. Thus, it seems that is is not able to draw the update first time receiving the signal. If I emit the signal two times in a row without changing the focus between the line edits it is also not able to update.
Can anyone explain why my solution actually works?? I think it is very strange.
-
could you pastebin the code for we can have a look ?
-
Here is part of the code:
@
connectSignalsAndSlots(){
// Code to connect textEdits to mye updateCoordinate slotsQObject::connect(ui_->lineEditX,SIGNAL(textEdited(const QString &)),widget2,SLOT(updateCoordinate(const QString &)));
QObject::connect(ui_->lineEditY,SIGNAL(textEdited(const QString &)),widget2,SLOT(updateCoordinate(const QString &)));
QObject::connect(ui_->lineEditZ,SIGNAL(textEdited(const QString &)),widget2,SLOT(updateCoordinate(const QString &)));
QObject::connect(ui_->pushButtonViewImage,SIGNAL(clicked()),this,SLOT(viewImage());
}
// SLOT updateCoordinate
updateCoordinate(const QString &)
{
x = ui_->lineEditX->text.toDouble();
y = ui_->lineEditX->text.toDouble();
z = ui_->lineEditX->text.toDouble();emit coordinateChange(x,y,z); ui_->lineEditX->setFocus(); ui_->lineEditY->setFocus(); ui_->lineEditX->setFocus(); emit coordinateChange(x,y,z)
}
// SLOT open Widget2 and connect signal from this widget to widget2
viewImage()
{
widget2Name* w = new widget2Name();
w->setWindowModality(Qt::WindowModal);
QObject::connect(this,SIGNAL(coordinateChange(double,double,double)),w,SLOT(updateImage(double,double,double)));
w->exec();
delete w;}
// SLOT updateImage in Widget2:
updateImage(double x, double y, double z)
{
for(int i = 0; i <numImages, i++)
{
// Some code to read the image I want (is a QByteArray -> QPixmap -> QImage)
QIcon thumbnail = QIcon(QPixmap::fromImage(image));
// Some code to draw the point on the image using (x,y,z)
QListWidgetItem* newItem = new QListWidgetItem(ui_.thumbnailWindow); //thumbnailWindow = QListWidget
newItem->setText("Some text");
newItem->setIcon(thumbnail);
}
}
@As I mentioned before I have tried the following to update it without emitting the signal twice:
- ui_->thumbnailWindow->update()
- ui_->thumbnailWindow->repaint();
- QApplicationCore::processEvents();
etc....
My current solution works but it is not a nice design....
-
i think you can use directly event from slot existed allready... from your QlineEdit widget... then use them to just do the job that update coordinate do, but only for each x or y or z data.
then emit a custom signal with the data and the origin of the data (two arguments).
Like that, you will have only one signal create, use these exist allready and not call three time the QlineEdit for ask text (because, in your design, when you add an entry in each QlineEdit, in fact, you finish by call three times each one... and call two signals 3 times...so for exemple this will gove you:
@
void your_class::on_lineEditX_textEdited(const QString &text) {
emit coordinateChange(text,"X");
}void your_class::on_lineEditY_textEdited(const QString &text) {
emit coordinateChange(text,"Y");
}void your_class::on_lineEditZ_textEdited(const QString &text) {
emit coordinateChange(text,"Y");
}
@
then at the reception you can connect this signal (don't forget to declare it inside "private signal:" from header file) to the slot you want and do a test condition for know if it is data from X, Y or Z and make the modificatio of your data to double at the end time for simplification.maybe there is some other design to do well (or better).
also... for your pushButton...
you can do same... use directly the on_pushButtonViewImage_clicked() { }
and do the job inside directly... use the signals exist allready to mount thinks and signal slots connection ONLY for go outside of your class embed the ui... -
Why not use QDoubleSpinBox ? That would avoid conversions
By the way, why do you need it to be window modal ?