QDialog or QMainWindow? - problem with OSX behavior



  • Let me explain the context :

    My application shown a custom QDialog that is the main use of my program (do a bike workout). To open this dialog, you have to browse a list and click a workout inside QMainWindow. The QDialog is then created with the QMainWindow as the parent.

    Win:
    https://www.dropbox.com/s/e6eiqyunfolqnjm/QDialog_Win.png
    On window, the behavior is as expected, a new window is opened (no maximize button on the window thought, just exit and "?")

    Mac:
    https://www.dropbox.com/s/p0a6fkwt7l4jcgp/QDialog_Mac.png
    On mac, there is no frame at all around the QDialog.
    I made custom button to fix the issue, because I need to windows to be shown fullscreen.
    .showFullScreen() doesn't work well on Mac (aspect ratio get changed somehow), so I use .showMaximized()
    Another problem is that there is no exit button on the QDialog, so user must know that pressing "esc" close the QDialog.

    I'm starting to wonder if using a QDialog for this part of my program was a mistake. This custom QDialog has 1400 line of code as now and is really complex. it's not just a QDialog that show a question with a simple "yes" or "no" like Qt intented QDialog to be. So what should I use as Window in that context, a QMainWindow? but having 2 MainWindow is bad right? What would be the best thing to use thinking I want to code less and have the same behavior on Win and OSX?

    Thanks in advance



  • Using theses flags fixed the Window issue
    @ Qt::WindowFlags flags = Qt::Window
    | Qt::WindowSystemMenuHint
    | Qt::WindowMaximizeButtonHint
    | Qt::WindowMinimizeButtonHint
    | Qt::WindowCloseButtonHint;
    this->setWindowFlags(flags);@

    but on mac I still have no buttons at all on the QDialog, I'll try using another QMainWindow maybe, but will have to change my code a lot..


  • Lifetime Qt Champion

    Hi,

    Are you sure you don't have the buttons, aren't these on the upper right ? But indeed, it doesn't look like the OS X style. Are you using a custom style or a stylesheet ?



  • Yes on OS X, If I want the QDialog to have button (top left default OSX button), I have to set it to be parentless, or it will just show a frameless QDialog like on the screenshot.

    The style should be a default QDialog, I'm not using a custom style (I did try, but it was too complex to make it work cross-platform) so now i'm trying to get Minimize, expand, and close OS default button on the QDialog, On windows I have it good, i'll see how I can "hack" it on OS X.. Because not having a close button is not really user-friendly, will post update

    Btw using 5.3.1 on latest OSX Mavericks
    thanks


  • Lifetime Qt Champion

    Can you make a minimal compilable example that shows how it doesn't work ?



  • Will do when I get home, I'll try a basic QMainWindow that open a QDialog with the basic QMainWindow as the parent, will post result after,
    thanks



  • From your screenshot on the mac it looks like you are using the Qt::Sheet style for dialogs on a mac. Which is how OSX and it's users prefer dialogs. But since you are trying to use a dialog in place of say a QWidget then you may need to override this setting for the dialog.

    Try:

    @
    setWindowFlags(Qt::Dialog);
    @

    For instance when I wanted to force sheet behavior before I used code like this:

    @
    #ifdef Q_WS_MAC
    setWindowFlags(Qt::Sheet);
    #else
    setWindowFlags(Qt::Dialog);
    #endif
    @

    And to address your questions, you can not have 2 QMainWIndows. It won't even let you as far as I know. To use a regular window that isn't a dialog you can just use a subclassed QWidget.



  • I think I found the problem on mac:

    The QDialog was opened in a child ui on MainWindow (not MainWindow directly). So the wrong parent was passed on creation. I changed the code to pass QMainWindow as the parent to the QDialog, but it still show the same "sheet" stylesheet instead of a normal QDialog. I have all the windows flags for a Qt::Dialog. The best thing for me would be to fix this, changing for a QWidget I won't have .exe, .accept() .reject() that are all used right now. Another way to fix it is to not pass a parent to the QDialog and I have my button on the top left.

    Here is my code :

    Opening the custom Dialog (workoutpage.cpp)

    @ qDebug() << "ParentMainWindow--:" << parentMainWindow;

    WorkoutDialog w(gotAntStick, tableModel->getWorkoutAtRow(sourceIndex),
                    this->antGearPage->sensorHR, this->antGearPage->sensorSPEED,
                    this->antGearPage->sensorCADENCE, this->antGearPage->sensorPOWER, parentMainWindow);
    

    w.exec();@

    Here is my CustomDialog constructor :

    @WorkoutDialog::WorkoutDialog(bool gotAntStick, Workout workout,
    Sensor sensorHR, Sensor sensorSPEED, Sensor sensorCADENCE, Sensor sensorPOWER,
    QWidget *parent) : QDialog(parent), ui(new Ui::WorkoutDialog) {

    ui->setupUi(this);
    
    loadInterface();
    

    ...
    } @

    LOG:
    ParentMainWindow-------------------: MainWindow(0x7fff59bf7a48, name = "MainWindow")



  • I think I can have the desired effect if I remove the parent when creating the Dialog. anyway the parent is not useful as my dialog is created only in a function and block execution until finished, so I don't need to pass a parent (it is for memory management purpose only right?)

    Then I would only need a button to "showFullscreen" on the QDialog. i.e: show the dialog as frameless and maximized (on mac). Kind of like a flash player when it is fullscreen I don't want anything to take space.

    Thank you!


  • Lifetime Qt Champion

    In the case of QDialog it's also to manage it's modality

    @ambershark why would 2 QMainWindow not be allowed ?



  • Maximus,

    In your case you may actually want a dialog, especially if you use exec(), accept(), etc. If you don't pass a parent object you would end up with a top level window which wouldn't allow the "sheet" in osx since it didn't have a parent window to attach the sheet. I think that might work for you. Give it a shot.

    @SGaist, I may be confusing that with not being able to have more than one/change the centralWidget() of a main window, but I thought I remember reading that you can only have one QMainWindow.

    It could also just be me thinking that having multiple main windows wouldn't make sense. I'm not even sure how it could be handled on OSX since the main windows links things like menubars directly to the system. Not sure how it would support 2 main windows.

    EDIT: I reread the docs on QMainWindow and you're right it doesn't look like there is anything stopping someone from having multiple QMainWindows. So I did some googling and saw that some people actually do just that. They tend to run into weird problems, like exiting one main window closes the entire app, and other weirdness, but it is absolutely possible. :)


  • Lifetime Qt Champion

    For the central widget part, a QStackedWidget is a good solution if you have several widgets you want to use



  • Yea that's what I use too. I was probably thinking of the centralWidget limitations when I was thinking you could only have one QMainWindow.

    Still not sure I would use multiple main windows in an actual app, can't think of a reason right now where I would do that over widget windows, but it's good to know it is possible. :)



  • Thanks for the discussion guy, I'll stick to a parentless QDialog and it should work fine. One other thing maybe I should open a bug on it. showFullscreen() still doesn't work as expected on Mavericks on 5.3.1, the windows get to full-screen but the widget inside it are all dis-proportioned. I think a work around could be :

    @showfullscreen() {
    if OS is Mac {
    setWindowFlag(frameless)
    showMaximized()
    save QSize, QPos
    }
    }
    showNormal() {
    setWindowFlag(QDialog)
    restore QSize, QPos
    }
    @

    Will try that when I get to use the mac and update this post,
    thanks!



  • Hi guys, just to let you know that i'm happy with the Windows result with a parentless QDialog. I also wanted my QMainWindow to be disabled while the QDialog is open so I had to disable MainWindow manually

    @//// Slot activated when QDialog is open and closed
    void MainWindow::hubLoopActive(bool active) {

    ui->widget_bottomMenu->setHubStatus(active);
    if (active) {
        ui->widget_bottomMenu->setGeneralMessage("Test general message now- active ", 5000);
    }
    else {
        ui->widget_bottomMenu->setGeneralMessage("Test general message now- done ", 5000);
    }
    this->setDisabled(active);  //disable QMainWindow manually@
    

    Here is the result :

    1- Normal window :
    https://www.dropbox.com/s/atsu1xgqrtqtxhf/ParentLessDialog.png

    2- Fullscreen window:
    https://www.dropbox.com/s/9hak37qd9fu8zg4/expandOverwrite.png


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.