QColorDialog does not respond
-
Hello, I need to pick a color, so I'm using QColorDialog for that and it works fine, but on Wasm the dialog doesn't appear at first, then the basic color appear but not the remainder, so it's not usable, and the second time I try to pick a color, it causes a stack overflow. Maybe there's a better way to use the ColorDialog. On my code I'm using another Dialog, QFileDialog, and for Wasm it uses a special method called QFileDialog::getOpenFileContent that works fine. Maybe there's the same for QColorDialog or it could be added ? I can also replace QColorDialog by a custom Dialog doing the same hoping it won't have the same problem.
Here's my code, nouveau() is the one using QFileDialog and works, and couleurNouveau() is the one using QColorDialog and hangs.
void MainWindow::nouveau() { //QWidget *parent = this; auto fileContentReady = [this](const QString &fileName, const QByteArray &fileContent) { if (fileName.isEmpty()) { // No file was selected } else { // Use fileName and fileContent meshModel.faces.clear(); meshModel.LoadFromObjectFile(fileContent); QTableWidgetItem *twi = new QTableWidgetItem(QString::number(meshModel.faces.size())); ui->tableCouleurs->setItem(0, 1, twi); dessineModele(this); //creeFaces2d(this); //trouveVoisinage(); ui->vue3d->fitInView(scene3d->itemsBoundingRect(), Qt::KeepAspectRatio); } }; QFileDialog::getOpenFileContent("fichier OBJ (*.obj)", fileContentReady); } void MainWindow::couleurNouveau() { const QColorDialog::ColorDialogOptions options = QColorDialog::NoEyeDropperButton; const QColor color = QColorDialog::getColor(Qt::green, this, "Choisir une couleur", options); if (color.isValid()) { int nb = ui->tableCouleurs->rowCount(); ui->tableCouleurs->setRowCount(nb+1); QTableWidgetItem *tiC = new QTableWidgetItem(""); QPixmap pixmap(15, 15); pixmap.fill(color); tiC->setIcon(QIcon(pixmap)); //tiC->setFlags(tiC->flags() ^ Qt::ItemIsEditable); ui->tableCouleurs->setItem(nb, 0, tiC); QTableWidgetItem *tiN = new QTableWidgetItem("0"); ui->tableCouleurs->setItem(nb, 1, tiN); QTableWidgetItem *tiT = new QTableWidgetItem("Piece"); ui->tableCouleurs->setItem(nb, 2, tiT); } }
-
@Gilboonet said in QColorDialog does not respond:
it uses a special method called QFileDialog::getOpenFileContent that works fine. Maybe there's the same for QColorDialog or it could be added ?
Haven't checked every detail of your code, but your "special methods" are static functions.
Here for
QFileDialog
and here for
QColorDialog
So you can try:
QColor QColorDialog::getColor(const QColor &initial = Qt::white, QWidget *parent = nullptr, const QString &title = QString(), QColorDialog::ColorDialogOptions options = ColorDialogOptions())
Edit:
Ah I see you use it already:
@Gilboonet said in QColorDialog does not respond:
const QColor color = QColorDialog::getColor(Qt::green, this, "Choisir une couleur", options);
Why it doesn't work?
-
@Gilboonet said in QColorDialog does not respond:
I say special method because at least for QFileDialog it has was specially added for Wasm if I remember correctly the doc (it was 2 years ago).
Ah while researching I found one of your topics :D
Unfortunately I don't know about any "special" changes made to
QFileDialog
for WASM, so you know probably more than I do in regard of this topic :) -
Well, I changed the way I use QColorDialog, and used open() instead of getColor() and it works. Maybe could it be useful for future Wasm users to have that on the doc ? Or maybe am I doing it wrong with getColor() ?
void MainWindow::couleurChoisie (QColor color) { if (color.isValid()) { int nb = ui->tableCouleurs->rowCount(); ui->tableCouleurs->setRowCount(nb+1); QTableWidgetItem *tiC = new QTableWidgetItem(""); QPixmap pixmap(15, 15); pixmap.fill(color); tiC->setIcon(QIcon(pixmap)); //tiC->setFlags(tiC->flags() ^ Qt::ItemIsEditable); ui->tableCouleurs->setItem(nb, 0, tiC); QTableWidgetItem *tiN = new QTableWidgetItem("0"); ui->tableCouleurs->setItem(nb, 1, tiN); QTableWidgetItem *tiT = new QTableWidgetItem("Piece"); ui->tableCouleurs->setItem(nb, 2, tiT); } } void MainWindow::couleurNouveau() { QColorDialog *dialog = new QColorDialog(this); connect( dialog, &QColorDialog::colorSelected, [=]( const QColor& color ) { couleurChoisie( color ); }); dialog->open(); }
-
@Gilboonet
Yes, I would imagine the staticQColorDialog::getColor()
might need attention/reimplementing. There is effectively a discussion of this in https://qtandeverything.blogspot.com/2019/05/exec-on-qt-webassembly.htmlTake for instance QColorDialog. Typical use is as such:
QColorDialog dlg(parent); dlg.exec(); QColor color = dlg.selectedColor();
Which is basically what QColorDialog::getColor does.
... and does not work with Qt WebAssembly, because exec() does not return to the same place as you expect! The call to selectedColor will never get called.
What you can do is use a non-modal dialog with the show() or in the case of QColorDialog open() function and use Qt's signal/slot API to retrieve the selected QColor.
If you want to suggest the WASM devs look at whether
getColor()
should work or provide other method you have to raise that at https://bugreports.qt.io/. If @lorn-potter sees this he might comment. -
@JonB said in QColorDialog does not respond:
Take for instance QColorDialog. Typical use is as such:
QColorDialog dlg(parent);
dlg.exec();
QColor color = dlg.selectedColor();Isn't
QDialog::exec()
not recommended anymore anyway?
Without double checking if I'm not mistaken, there's a hint in the documentation to useQDialog::open()
to prevent (other) undefined/unwanted behavior. -
@JonB Thank you for your reply, for the moment I will cope with open() function + signal/slot as it work fine. It's only my second Qt (and also) C++ project, I'm a long way to be experienced enough to suggest anything to Qt developers, but I read many times that exec() is not a good idea for Dialogs on Wasm, and at the same time, an hour ago I was testing and I hit two times the New button that opens 2 FileOpenDialogs, thing that a simple open() cannot prevent.
-
@Gilboonet said in QColorDialog does not respond:
I read many times that exec() is not a good idea for Dialogs on Wasm
Like I said above,
QDialog::exec()
is actually not recommended to use anywhere.Note: Avoid using this function; instead, use open(). Unlike exec(), open() is asynchronous, and does not spin an additional event loop. This prevents a series of dangerous bugs from happening (e.g. deleting the dialog's parent while the dialog is open via exec()). When using open() you can connect to the finished() signal of QDialog to be notified when the dialog is closed.
( https://doc.qt.io/qt-6/qdialog.html#exec )
But if you know what you are doing it still works in "normal" projects... but as you figured out, in WASM it apparently it causes problems.
I hit two times the New button that opens 2 FileOpenDialogs, thing that a simple open() cannot prevent.
You can work around that for example with a member variable which stores if the dialog is open already.
Then you could reset the "flag" in the function connected to theQDialog::finished
signal -
@Gilboonet said in QColorDialog does not respond:
but I read many times that exec() is not a good idea for Dialogs on Wasm
Yes. Although I have not used WASM, dialog
exec()
blocks the application while waiting for an answer/interaction with the user. This is fine in a desktop application, but I can believe it is not suited when converting to a web application. It does not surprise me that any such calls would be to be be avoided in WASM, and is perhaps why you said they made a change toQFileDialog
. -
@JonB At first I tried to run Wasm using asyncify parameter but it didn't change anything. I suspect that there are others things that are not fitted for Wasm, for example, click on a ToolBar ToolButton that opens a popup menu make Wasm crash, just like right click to open a context menu. I'm still hoping that there's a way to do those things with Wasm as common ways don't work. For the moment I'm simply putting my actions on ToolBars.
-