Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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

    Hi
    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.
    https://stackoverflow.com/questions/18074798/layers-on-qgraphicsview

    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);
        scene->setSceneRect(-800,-400,1600,800);
    view = new View(this);
        view->setScene(scene);
    

    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)
    {
        scene->setPenWidth(arg1);
    
    }
    
    void MainWindow::on_fillColorButton_clicked()
    {
    
        QColor color = QColorDialog::getColor(Qt::cyan,this);
        if(color.isValid()){
            QString fillcolorQss= QString("Background-color : %1").arg(color.name());
            ui->fillColorButton->setStyleSheet(fillcolorQss);
            scene->setFillColor(color);
        }
    }
    
    void MainWindow::on_showGridCheckbox_toggled(bool checked)
    {
        view->setDrawGridLines(checked);
    }
    
    void MainWindow::on_centreSceneButton_clicked()
    {
        view->centerOn(QPoint(0,0));
    }
    

    Thank you for helping me out !


  • Lifetime Qt Champion

    Hi
    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)
    {
        scene->setPenWidth(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
    https://doc.qt.io/qt-5/qstackedwidget.html#currentChanged
    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)
    {
        curScene->setPenWidth(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

    @newToQt26
    Hi
    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.