I'm having an issue inheriting from QFileDialog and controlling the enabling/disabling of the Open button as needed. I've read a lot of posts online, but no one seems to be having my problem. I've tried a number of things on my own, but don't seem to be working this one out.

What I'm tasked with:

I need to be able to keep the inherited dialog's Open button disabled (unclickable) as long as the selection is not a file or not of a specified extension (which is partially handled by filtering, though All Files is an option), and also as long as the content of the selected file is not of the correct proprietary format (which is where my issue shows up). This means when the user selects a file from the list, I read a format specifier from the head of the file, and need to keep the Open button disabled as long as the format is not correct for the current run of the application.

I am very much trying to avoid a user having to get a separate "Are you sure?" dialog. I will show an error in the dialog itself, and want to only enable the Open button when a file with the correct type and format is selected.

What I've done:

I have created a class called MyFileDialog (code shown below - name changed to protect the innocent) which inherits QFileDialog and connects the QFileDialog::currentChanged() signal to a local slot function fileSelectionChanged(). The slot calls a helper function which opens and checks the file for valid format, and returns a bool for validity. The slot receives this return value and grabs the Open button (retrieved from the file dialog button box and stored at construction time) and sets the Open button's enabled state to that bool value.

When I run the program and open the file dialog and click on a file that does not have a valid format, the Open button remains enabled which is incorrect, but when I debug through the given code, I see that I do have the correct button (the text of the button shows as "&Open"), and that the button was set enabled = false (both tests shown in the code below).

I assume that there is a timing issue here, so that I'm responding to a signal, and then maybe sometime after I respond the button is reset to enabled = true by the QFileDialog itself. Not sure how to get passed this if that's the case.

I also tried overriding the mouseReleaseEvent() (code not shown). I get into this event handler when I click anywhere in the QFileDialog other than sub-widgets. If I click on any sub-widget (such as the list view, the folder drop-down, the file name text box, or any of the buttons) I don't get into the event handler at all. It seems that QFileDialog is accepting and not propagating the event. Does anybody see a way around this? I really need this to work as described.

The following code has been fully tested before submitting:

Qt Code:
  1. // Class declaration for MyFileDialog
  2.  
  3. #pragma once
  4.  
  5. #include <qfiledialog.h>
  6.  
  7. class MyFileDialog : public QFileDialog
  8. {
  9. Q_OBJECT
  10.  
  11. public:
  12. //! \brief CTOR
  13. MyFileDialog(QWidget* parent, QString directory);
  14.  
  15. //! \brief DTOR
  16. virtual ~MyFileDialog() {}
  17.  
  18. protected slots:
  19. virtual void fileSelectionChanged(const QString& file);
  20.  
  21. protected:
  22. bool formatCheck(const QString& file);
  23.  
  24. private:
  25. QPushButton* myOpenButton;
  26. };
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. // Class definition for MyFileDialog
  2.  
  3. #include "MyFileDialog.h"
  4. #include "qdialogbuttonbox.h"
  5. #include "qpushbutton.h"
  6.  
  7. MyFileDialog::MyFileDialog(QWidget* parent, QString startdir)
  8. : QFileDialog(parent, tr("Load Correct Format"), startdir),
  9. myOpenButton(0)
  10. {
  11. // for an Open File dialog, get the Open button for later use
  12. if (acceptMode() == QFileDialog::AcceptOpen)
  13. {
  14. QDialogButtonBox *button_box = findChild<QDialogButtonBox *>();
  15. if (button_box) {
  16. myOpenButton = (QPushButton *)button_box->button(QDialogButtonBox::Open);
  17.  
  18. // the following line shows that I've retrieved
  19. // a button with the text: "&Open".
  20. QString buttonText = myOpenButton->text();
  21. }
  22. }
  23.  
  24. connect(this, SIGNAL(currentChanged(const QString&)), this, SLOT(fileSelectionChanged(const QString&)));
  25. }
  26.  
  27. void MyFileDialog::fileSelectionChanged(const QString& file)
  28. {
  29. QFileInfo fileInfo(file);
  30. if (fileInfo.exists())
  31. {
  32. if (myOpenButton) {
  33. bool isvalid = formatCheck(file);
  34. myOpenButton->setEnabled(isvalid);
  35.  
  36. // the following two lines for testing. Shows the
  37. // button's text is "&Open" and the enabled state is
  38. // the same as the value of the "isvalid" variable.
  39. QString buttonText = myOpenButton->text();
  40. bool enabled = myOpenButton->isEnabled();
  41. }
  42. }
  43. }
  44.  
  45. bool MyFileDialog::formatCheck(const QString& file)
  46. {
  47. // opens the file and returns the boolean result
  48. // of the format check.
  49.  
  50. // true leaves the button enabled; false also leaves the button enabled
  51. //bool result = true;
  52. bool result = false;
  53.  
  54. return result;
  55. }
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. // main() function instantiating and exec'ing MyFileDialog
  2.  
  3. #include "MyFileDialog.h"
  4.  
  5. int main(int argc, char *argv[])
  6. {
  7. MyFileDialog d(parent, "@C:\tmp");
  8. d.exec();
  9. }
To copy to clipboard, switch view to plain text mode