Qt World Summit: Submit your Presentation

QStackedWidget and adding new QGraphicsView to its pages

  • Hey everyone !
    This is my first post here.. I am fairly new to Qt. I have been trying to develop a paint like application. All the basic features and user interface is pretty much ready. I am stuck with the functionality of layers.

    Basically , I have to create layers like the one in photoshop. I should be able to add , remove layers on clicking buttons/menu. I should be able to draw rectItems on each layer and apply different properties on each layer .
    For the same purpose I need stacked Widget, mapped to a Tree view , and with every new page added , I need a new View and Scene to be displayed. I am able to add new pages to StackedWidget , and add the view to it. But the problem is every new page is not showing its own view. Its like they are sharing the same view. I want the view of 1st page to hold its own contents and view of 2nd page to have its own contents.

    I have derived custom View and Scene classes from QGRaphicsView and QGraphicsScene respectively. Also by clicking the item in QTreeView, the corresponding stackedPage should be displayed .
    I am attaching screenshot of my application for better understanding. !paintAppRun.png

    Can anyone help me build the idea? Or help me with implementing this?
    Sorry for such a long description. Just a newbie trying to explain the problem.

    Thank you for reading :)

  • Lifetime Qt Champion

    we like long good descriptions here :)
    I'm not 100% sure how layers would work with a QStackedWidget as then each layer would be like its own
    document and not draw on top of each other.

    Did you see QGraphicsItemGroup ?
    You could use that for layers as you can then hide/show all items that is on a layer.

    In any case, if you want like separate documents, then show how you add the new
    QGraphicsView and QGraphicsScene to a new page.
    It should work fine but something must be up if that is not what you are getting.

  • Hey !
    Thanks for replying . I was thinking to make the stackedWidget transparent , that way I can see the items on every layer .. I am not sure about QGraphicsItemGroup , but I'll check that out !

    As of now, I added another Qt designer Form class (DrawingBoard) , in which I set up my GraphicsView and Scene , and then in mainWindow.cpp in the Add layer fucntion:

    ui->stackedWidget->addWidget(new DrawingBoard);

    which works fine ! I get a new fresh view & scene everytime I add a layer . But the new problem is , all my Menu and actions and functionalities are in mainwindow.cpp ! They dont seem to work with the selections in subsequent pages added via above code.

    pen properties,brush properties, zoom , backgroundcolor , undo/redo , everything works just with the 1st view , which has been set up in mainWindow.cpp:

    scene = new Scene(this);
    view = new View(this);

    So , now I dont know how to make all the new Views & scenes accessible to mainWindow tools.

    For example, I have pasted the part of the mainwindow.cpp code here:

    void MainWindow::on_penWidthSpinBox_valueChanged(int arg1)
    void MainWindow::on_fillColorButton_clicked()
        QColor color = QColorDialog::getColor(Qt::cyan,this);
            QString fillcolorQss= QString("Background-color : %1").arg(color.name());
    void MainWindow::on_showGridCheckbox_toggled(bool checked)
    void MainWindow::on_centreSceneButton_clicked()

    Thank you for helping me out !

  • Lifetime Qt Champion

    QStackWidget will hide/show the other pages so not sure even if transparent, it will work
    as we would like.

    But lets talk about MainWindow functions

    void MainWindow::on_penWidthSpinBox_valueChanged(int arg1)
    here we use the scene we have in main window but we want to affect the currents pages
    scene or view 
    so i would add to DrawingBoard, some access function to allow gettings its scene and view.
    like getScene() and getView() that just returns its variables.

    Then i would hook up
    to a slot
    and use getScene() and getView() from DrawingBoard to get the current view/scene
    You could use 2 member variables in MainWindow
    curSecne and curView
    and from start set to the ones MainWidnow has
    but when you then switch page, we set to others.

    void MainWindow::on_penWidthSpinBox_valueChanged(int arg1)

    so we use 2 variables to point to the scene or view that is active.

    I hope this makes sense :)

  • @mrjj Hey ! Sorry for the late reply ! It was a long weekend !

    This surely makes much more sense . I'll try this one out and let you know ! Thank you so much for helping me out

    About stackedWidget , I'll look into it as well .. I think there might be some problems with transparency , because I did try it earlier and I didn't get desired results .

    And I'll mark this solved as soon as I get this right ( in case I have any doubts while implementing it!)
    Thanks again :)

  • @mrjj Hey ! I tried it. It worked like charm. along with it , I used QMap too.
    Thank you so much for helping :)

  • Lifetime Qt Champion

    Good to hear. :)

    If the user can add or delete layers, it's pretty important you make sure
    curScene/curView always points to something valid as else you get a nasty crash.