[Solved] How can I change the shape of a widget?



  • I want to create a QLabel with a triangle border (like the left border in this http://www.tuangou.com.br/images/etiqueta.png ). But I need help. I don't know how to start. Is it posible to do it with a CSS?
    Sorry if don't post a code, it's because I'm new in QT so I have no idea.

    I'm using QT4.8. Any Python or C++ example can help.

    Thank you in advance and excuse my english. Greetings!



  • Inherit QLabel class to your own custom LabeledLabel and reimplement QWidget::paintEvent... in that method you can draw that backgroud and rotate also the text.

    @
    #include <QLabel>
    #include <QPainter>

    class LabeledLabel : public QLabel
    {
    Q_OBJECT
    public:
    LabeledLabel(...);

    protected:
    void paintEvent(QPaintEvent*)
    {
    QPainter p(this);
    // draw...
    }
    };
    @



  • And you should use QWidget::setMask()
    Have a look at the Shaped Clock Example...


  • Moderators

    There are more easy ways and more complex ways to achieve what you want.

    • If your label should have a fixed size you can just set the background via stylesheet with a image file
    • with the custom paint method your free to do anything you like buts it's way more work involved, which may be a problem as newbie for you?

    Setting a mask only makes sense if it should be a top-level widget and only if you need to ignore input events on the masked area. Using of masks never leads to a nice result visual IMHO unless you just use straight edges (since it's a bitmap -> no antialiasing).



  • Using a mask can result in quite nice looking widgets, even if they don't have striaght edges... it is not easy though...
    But you are right: it only makes sense for top-level widgets.



  • Thanks to Peppy, Mr. Universe and raven-worx.

    I'm subclassing QLabel. Each instance can take different sizes, so I can't use an image file. Either with setting a mask because is not a top-level widget, so the best option will be using the paintEvent.

    I don't want to abuse, so first I will read some tutorials about this and try to do it by myself.

    Thank you again!



  • Widgets are always rectangular, you cannot get away from this, but you could go for drawing something different within the bounds of that rectangle and create the illusion of a different shape.

    If you want different sizes - use a vector image, e.g. a SVG, it scales without resolution loss.



  • Thanks utcenter! I will read about vector images.

    Well, I did it with the paintEvent, but I need help for some details.
    This is the code. finallly I subclass from QWidget

    [code]
    class MyWidget(QWidget):
    def init(self):
    super(MyWidget, self).init( )

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(painter.Antialiasing)
        painter.setPen(QPen( QBrush("#000"), 1 ))
        painter.setBrush( QBrush(QColor("#000")) )
        point1 = QPoint(0,0)
        point2 = QPoint(80, 0)
        point3 = QPoint(92, 10)
        point4 = QPoint(80, 20)
        point5= QPoint(0,20)
        poly = QPolygon((point1, point2, point3, point4, point5))
        painter.drawPolygon(poly)
    

    [/code]

    The thing is that the widget will be used into a QTableWidget as a cellWidget. The cells will take differents spans, so the widget size could adapt to the cell span, like any other widget. And this is my question:
    ¿How other widgets change the size depending on the container size? or ¿Is the container (in this case the QTableWidget) who handles the widget size?

    In the paintEvent I want to get the size of the spanned cell and calculate the widget size. Also, I can override the setSpan function of the QTableWidget and set the widget width. But I want to know wich is the best practice.

    Thank you and excuse my english!



  • Maybe was obvius... with the resizeEvent, using QResizeEvent.size() and QResizeEvent.oldSize()

    Thanks for all!

    Greetings


Log in to reply
 

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