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

Is there any method for drawing grid on QWidget ?



  • Hello, Everyone. I want to draw grid on widget that is my main display widget. In other hand, i found any example, they using QGraphicsScene and QGraphicsView. My case is QWidget ? help me


  • Moderators



  • @JKSH But my drawing Widget is constructed to layout in Mainwindow. So i can't activate my painter into QWidget.


  • Qt Champions 2017

    The widget which you are adding to layout has to be custom widget. In the custom widget reimplement the paintEvent(..) function. You create the object of this custom widget & add to layout.


  • Lifetime Qt Champion



  • I tried to write custom widget. but it doesn't work.
    /////Widget.cpp///
    myCustomWidget = new QWidget;
    myCustomWidget->resize(800,600);
    QVBoxLayout *myBoxLayout = new QVBoxLayout;
    setLayout(myBoxLayout);
    scene = new MapGraphicsScene(this);
    view = new MapGraphicsView(scene,myCustomWidget);
    myBoxLayout->addWidget(view);
    ////anotherWidget.cpp//
    void anotherWidget::paintEvent(QPaintEvent *event)
    {
    QPainter painter(this);

      int step = GRID_STEP;
    
      painter.setPen(Qt::black);
      const QRectF rect = event->rect();
      qreal start = round(rect.top(), step);
      if (start > rect.top())
      {
         start -= step;
      }
      for (qreal y = start - step; y < rect.bottom(); )
      {
         y += step;
         painter.drawLine(rect.left(), y, rect.right(), y);
      }
      // now draw vertical grid
      start = round(rect.left(), step);
      if (start > rect.left())
      {
         start -= step;
      }
      for (qreal x = start - step; x < rect.right(); )
      {
         x += step;
         painter.drawLine(x, rect.top(), x, rect.bottom());
      }
      painter.end();
    

    }

    Result like this:
    0_1542290941686_Ubuntu 64-bit-2018-11-15-22-55-22.png

    Behind of Array has to be front of widget.


  • Moderators

    @Munkhtamir
    you have to create it after the other Widget, for it to be on top by default, otherwise you can call raise() on your grid-widget to make it the top most item.

    But I force a problem for after this, and thatone is because of transparency/opacity

    inside paintEvent you should call the base implementation

    QWidget::paintEvent(event);
    QPainter painter(this);
    ....

    That way your widget will react to style sheets, and you can set a simple stylesheet like

    setStyleSheet(background-color:transparent;);


    Edit: example:

    //Custom class .h
    #include <QWidget>
    
    class GridWidget : public QWidget
    {
        Q_OBJECT
    public:
        explicit GridWidget(QWidget *parent = nullptr);
    
        void setGridDistance(int distance);
    
    protected:
        void paintEvent(QPaintEvent *event);
    
        int m_GridDistance = 20;
    };
    
    
    //Customclass .cpp
    #include "gridwidget.h"
    
    #include <QPainter>
    
    GridWidget::GridWidget(QWidget *parent) : QWidget(parent)
    {
        setStyleSheet("background-color:transparent;");
    }
    
    void GridWidget::setGridDistance(int distance)
    {
        m_GridDistance = distance;
        update();
    }
    
    void GridWidget::paintEvent(QPaintEvent *event)
    {
        QWidget::paintEvent(event);
    
        QPainter p(this);
        p.setPen(QPen(Qt::white,3));
        for(int i(0); i < width(); i += m_GridDistance){
            p.drawLine(i,0,i,height());
        }
    
        for(int i(0); i < height(); i += m_GridDistance){
            p.drawLine(0,i,width(),i);
        }
    }
    
    //Example main.cpp black widget with GridWidget ontop;
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QWidget *w = new QWidget();
        w->setStyleSheet("background-color:black");
        w->resize(200,200);
        w->show();
    
        QHBoxLayout *layout = new QHBoxLayout(w);
        layout->setMargin(0);
        layout->addWidget(new GridWidget());
    
        return a.exec();
    } 
    

Log in to reply