Draw a QFrame-like rectangle



  • I am trying to draw a rectangle that is QFrame-like with 3D border, but I only ever get a simple 1-pixel rectangle.

    When testing the simplest case, that of a box with a 10-pixels border, my simplified test-code :

    void Win::paintEvent(QPaintEvent * event)
    {
      QWidget::paintEvent(event);
      QPainter painter(this);
      QStyleOptionFrame  option;
      option.initFrom(this);
      option.rect = QRect(100,100,100,100);
      option.lineWidth = 10;
      option.frameShape = QFrame::Box;
      style()->drawPrimitive(QStyle::PE_Frame,  &option,  &painter,  this);
    }
    

    The above draws a 1-pixel rectangle. If I replace the drawPrimitive call with :

    painter.setPen(QPen(Qt::red, 10));
    painter.drawRect(QRect(100,100,100,100));
    

    then the rectangle is correct.

    What am I doing wrong ?


  • Qt Champions 2016

    Hi
    Might need
    Option.state = QStyle::State_Sunken; // or what ever
    Since values might be random (not all set by initFrom) ,
    you must set all used for a PE_X style.

    If still not working, check out QFrame source for what it really needs.

    This works for me. ( for line)

           QStyleOptionFrame option;
            option.initFrom(this);
            option.state = QStyle::State_Sunken;
            option.frameShape = QFrame::HLine;
            style()->drawPrimitive(QStyle::PE_Frame, &option, &painter, this);
    


  • @mrjj :

    I have tried to assign every possible documented member variable, but no go.
    The code now looks like :

    void Win::paintEvent(QPaintEvent * event)
    {
      QWidget::paintEvent(event);
      QPainter painter(this);
      QStyleOptionFrame  option;
      option.initFrom(this);
      option.rect = QRect(100,100,100,100);
      option.lineWidth = 10;
      option.frameShape = QFrame::Box;
      option.state = QStyle::State_Sunken;
      option.direction = Qt::LeftToRight;
      option.features = QStyleOptionFrame::Rounded;
      option.fontMetrics = QFontMetrics(QFont("Arial"));
      option.midLineWidth = 4;
      option.type = QStyleOption::SO_Frame;
      style()->drawPrimitive(QStyle::PE_Frame,  &option,  &painter,  this);
    }
    

    I have also tried to take out the call to option.initFrom(this);, but this changed nothing.
    I have even changed option.frameShape = QFrame::HLine;, but I still get a 1-pixel rectangle/line.


  • Moderators

    You are using the wrong drawing function and element. It should be

    style()->drawControl(QStyle::CE_ShapedFrame, &option, &painter, this);
    


  • @Chris-Kawa :

    YES! This was it.
    Unfortunate that drawPrimitive was wrongly recommended so many times on StackOverflow and elsewhere.
    Many thanks.


Log in to reply
 

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