Child QFileDialog paint problem
Solved
General and Desktop
-
The QFileDialog displays as a transparent frame. I am including a small test program. Thanks!
#------------------------------------------------- # # Project created by QtCreator 2018-08-21T10:24:03 # #------------------------------------------------- QT += core gui opengl multimedia multimediawidgets TARGET = QFileDialogTest TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 CONFIG += c++11 SOURCES += \ main.cpp \ mainwindow.cpp \ globalfunctions.cpp \ mydialogclass.cpp HEADERS += \ globals.h \ mainwindow.h \ mydialogclass.h # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
globals.h :
#ifndef GLOBALS_H #define GLOBALS_H #include <iostream> #include <cstdio> #include <stdlib.h> #include <string> #include <stdio.h> #include <QApplication> #include <QColor> #include <QCoreApplication> #include <QDebug> #include <QDesktopWidget> #include <QDialog> #include <QDir> #include <QFile> #include <QFileDialog> #include <QMainWindow> #include <QPaintDevice> #include <QPainter> #include <QPushButton> #include <QRadioButton> #include <QRect> #include <QScreen> #include <QString> #include <QStringList> #include <QWindow> #include <QtCore> #include <QtDebug> #include <QtGui> using std::cout; using std::cin; //==================== constants ==================== static const QColor G_RED = QColor(255,0,0,255); static const QColor G_GREEN = QColor(0,255,0,255); static const QColor G_BLUE = QColor(0,0,255,255); //==================== functions ==================== void gSizeAndCenterWidget (QWidget* widget, int width, int height); #endif // GLOBALS_H
globalfunctions.cpp :
#ifndef GLOBALS_H #include "globals.h" #endif //---------- gSizeAndCenterWidget --------- void gSizeAndCenterWidget (QWidget* widget, int width, int height) { int x,y; int screenWidth; int screenHeight; QDesktopWidget* desktop = QApplication::desktop(); screenWidth = desktop->width(); screenHeight = desktop->height(); x = (screenWidth - width)/2; y = (screenHeight - height)/2; widget->setGeometry (x, y, width, height); }//gSizeAndCenterWidget
mainwindow.h :
#ifndef MAINWINDOW_H #define MAINWINDOW_H #ifndef GLOBALS_H #include "globals.h" #endif #ifndef MYDIALOGCLASS_H #include "mydialogclass.h" #endif const static int MW_WIDTH = 500; const static int MW_HEIGHT = 400; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); private: QPushButton *dialogButt; MyDialogClass *rootDialog; protected: void paintEvent(QPaintEvent*); private slots: void SlotDoDialog(); }; #endif // MAINWINDOW_H
mainwindow.cpp :
#include "mainwindow.h" //---------- MainWindow Constructor ---------- MainWindow :: MainWindow(QWidget *parent) : QMainWindow(parent) { qDebug()<<"CONSTRUCTOR MainWindow"; gSizeAndCenterWidget (this, MW_WIDTH, MW_HEIGHT); dialogButt = new QPushButton("Do Dialog", this); dialogButt->setGeometry(100, 100, 100, 28); connect(dialogButt,&QPushButton::clicked,this, &MainWindow::SlotDoDialog); rootDialog = nullptr; } //---------- MainWindow Destructor ---------- MainWindow :: ~MainWindow() { qDebug()<<"DESTRUCTOR MainWindow"; } //---------- SlotDoDialog ---------- void MainWindow :: SlotDoDialog(){ if (rootDialog != nullptr) return; qDebug()<<" SlotDoDialog"; rootDialog = new MyDialogClass(this, Qt::Dialog); gSizeAndCenterWidget (rootDialog, (MW_WIDTH - 100), (MW_HEIGHT - 100)); rootDialog->exec(); } //---------- paintEvent ---------- void MainWindow :: paintEvent(QPaintEvent* event) { QPainter* painter = new QPainter(this); int x = (this->width() - 100) + (int)(50 + (rand() % 10)); int y = (this->height() - 40); QRect myRect(x,y,8,8); painter->fillRect(myRect, G_RED); delete painter; update(); }
mydialogclass.h :
#ifndef MYDIALOGCLASS_H #define MYDIALOGCLASS_H #ifndef GLOBALS_H #include "globals.h" #endif class MyDialogClass : public QDialog { public: MyDialogClass(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::Dialog); ~MyDialogClass(); private: QPushButton *anotherDialogButt; QPushButton *fileDialogButt; protected: void paintEvent(QPaintEvent*); private slots: void slotDoAnotherDialog(); void slotDoFileDialog(); }; #endif // MYDIALOGCLASS_H
mydialogclass.cpp :
#include "mydialogclass.h" //---------- MyDialogClass CONSTRUCTOR ---------- MyDialogClass :: MyDialogClass(QWidget *parent, Qt::WindowFlags f) : QDialog (parent, f) { qDebug()<<"CONSTRUCTOR MyDialogClass"; anotherDialogButt = new QPushButton("Do Child Dialog", this); anotherDialogButt->setGeometry(100, 100, 150, 28); connect(anotherDialogButt,&QPushButton::clicked,this, &MyDialogClass::slotDoAnotherDialog); fileDialogButt = new QPushButton("Do QFileDialog", this); fileDialogButt->setGeometry(100, 140, 150, 28); connect(fileDialogButt,&QPushButton::clicked,this, &MyDialogClass::slotDoFileDialog); } //---------- MyDialogClass DESTRUCTOR ---------- MyDialogClass :: ~MyDialogClass(){ qDebug()<<"DESTRUCTOR MyDialogClass"; } //---------- paintEvent ---------- void MyDialogClass :: paintEvent(QPaintEvent *e) { QPainter* painter = new QPainter(this); int x = (this->width() - 100) + (int)(50 + (rand() % 10)); int y = (this->height() - 40); QRect myRect(x,y,8,8); painter->fillRect(myRect, G_GREEN); delete painter; update(); } //---------- slotDoAnotherDialog ---------- void MyDialogClass :: slotDoAnotherDialog(){ qDebug()<<" slotDoAnotherDialog"; MyDialogClass *anotherDialog = new MyDialogClass(this); anotherDialog->exec(); } //---------- slotDoFileDialog ---------- void MyDialogClass :: slotDoFileDialog(){ qDebug()<<" slotDoFileDialog"; QString fileName = QFileDialog::getOpenFileName(this, "Open Image", "~/", "Image Files (*.png *.jpg *.bmp)"); qDebug()<<"fileName: "<<fileName; }
main.cpp :
#include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
-
I agree that calling update() in paintEvent() is not good, but it usually works.
The problem is solved. I am running Linux Mint, and the native dialog was not painting. Solved by setting the "QFileDialog::DontUseNativeDialog" option.
//---------- slotDoFileDialog ---------- void MyDialogClass :: slotDoFileDialog(){ qDebug()<<" slotDoFileDialog"; QFileDialog myFileDialog(this, Qt::Dialog); myFileDialog.setOption(QFileDialog::DontUseNativeDialog, true); myFileDialog.setFileMode(QFileDialog::DirectoryOnly); myFileDialog.exec(); }