Results 1 to 19 of 19

Thread: How to insert a drawing in QWidget in Qt Designer form ?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Apr 2010
    Location
    Italia
    Posts
    149
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default How to insert a drawing in QWidget in Qt Designer form ?

    I created a dialog in Qt Designer di Qt 6.5 per Windows 10 in which I put a QWidget that will contain a drawing made with QPainter in my application code. What should I write in the paintEvent(QPaintEvent* event) where the drawing is created and that I want to insert in the QWidget of the Qt Designer form ?
    To better understand what I'm saying, I attach a screenshot of what I have now: a red led drawn with QPainter in the :aintEvent(QPaintEvent* event) code of my application and a check box inserted by Qt Designer.
    Here instead the paintEvent method in which I draw the led:

    Qt Code:
    1. void Led::paintEvent(QPaintEvent* event)
    2. {
    3. Q_UNUSED(event);
    4.  
    5. QPainter p(this);
    6.  
    7. QRect geo = ui.widgetLed->geometry();
    8. int width = geo.width();
    9. int height = geo.height();
    10.  
    11. int x = 0, y = 0;
    12. if (alignment_ & Qt::AlignLeft)
    13. x = 0;
    14. else if (alignment_ & Qt::AlignRight)
    15. x = width - diamX_;
    16. else if (alignment_ & Qt::AlignHCenter)
    17. x = (width - diamX_) / 2;
    18. else if (alignment_ & Qt::AlignJustify)
    19. x = 0;
    20.  
    21. if (alignment_ & Qt::AlignTop)
    22. y = 0;
    23. else if (alignment_ & Qt::AlignBottom)
    24. y = height - diamY_;
    25. else if (alignment_ & Qt::AlignVCenter)
    26. y = (height - diamY_) / 2;
    27.  
    28. QRadialGradient g(x + diamX_ / 2, y + diamY_ / 2, diamX_ * 0.4,
    29. diamX_ * 0.4, diamY_ * 0.4);
    30.  
    31. g.setColorAt(0, Qt::white);
    32. if (state_)
    33. g.setColorAt(1, color_);
    34. else
    35. g.setColorAt(1, Qt::black);
    36. QBrush brush(g);
    37.  
    38. p.setPen(color_);
    39. p.setRenderHint(QPainter::Antialiasing, true);
    40. p.setBrush(brush);
    41. p.drawEllipse(x, y, diamX_ - 1, diamY_ - 1);
    42.  
    43. if (flashRate_ > 0 && flashing_)
    44. timer_->start(flashRate_);
    45. else
    46. timer_->stop();
    47. }
    To copy to clipboard, switch view to plain text mode 

    All this to be able to see the check box and the led side by side and not as in the figure I have attached.
    Attached Images Attached Images
    Last edited by giorgik; 4th May 2023 at 12:41.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to insert a drawing in QWidget in Qt Designer form ?

    If you want to insert a picture of an LED, then do this:

    - In Qt Designer, you insert a QLabel widget where you want to draw the LED. If you want the label to look like an LED in Designer, then you can create a pixmap (see below) and set that as the "pixmap" property for the QLabel. It is just a picture, you can't change any of the "LED" properties unless you use different pixmaps to simulate the appearance.

    - In your application, you draw the LED into a QPixmap of the right size, then call QLabel::setPixmap().

    - Based on your current code for your LED widget, replace the paintEvent() or add this new method to create the pixmap instead of painting to the screen. (If you keep the paintEvent(), this will allow you to use the widget either as a QWidget or to create a pixmap for a QLabel).

    Qt Code:
    1. QPixmap Led_0_6_1::createPixmap( const QSize & wxh )
    2. {
    3. QPixmap pixmap( wxh );
    4. QPainter painter( &pixmap );
    5. painter.setRenderHint(QPainter::Antialiasing, true);
    6.  
    7. QString ledShapeAndColor = shapes[m_shape];
    8.  
    9. if (m_value)
    10. ledShapeAndColor.append(colors[m_onColor]);
    11. else
    12. ledShapeAndColor.append(colors[m_offColor]);
    13.  
    14. QSvgRenderer renderer;
    15. renderer.load(ledShapeAndColor);
    16. renderer.render(&painter);
    17.  
    18. return pixmap;
    19. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. // In your application:
    2.  
    3. QSize size = myLabel->size();
    4.  
    5. using LED = Led_6_0_1;
    6.  
    7. LED led; // Temporary - this is not a widget to appear on screen. It is used simply for drawing the pixmap.
    8.  
    9. // Set shape and colors for led
    10. led.setShape( LED::Circle );
    11. led.setOnColor( LED::Red );
    12. led.setOffColor( LED::Grey );
    13.  
    14. // Create the pixmap and install it
    15. QPixmap pixmap = led.createPixmap( size );
    16. myLabel->setPixmap( pixmap );
    To copy to clipboard, switch view to plain text mode 

    If you want to change LED colors or shape in response to user input, then you need to change the pixmap by running this code again with the new properties and setting the pixmap again.

    Another option would be to use Qt Designer to insert a QLabel at any place you want an LED, then using the Designer's "Promote to" feature to change the QLabel to an LED. I do not know if this will let you change properties in Qt Designer, but at least your LED will be accessible in your application as an Led_6_0_1 instance and you can change the properties at run time for your app instead of having to create a new pixmap for every change.

    It would really be much easier if you got your plugin to work instead.
    Last edited by d_stranz; 4th May 2023 at 20:23.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Apr 2010
    Location
    Italia
    Posts
    149
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Red face Re: How to insert a drawing in QWidget in Qt Designer form ?

    Quote Originally Posted by d_stranz View Post
    It would really be much easier if you got your plugin to work instead.
    And that's exactly what I'm doing and I've asked for help: creating LED plugins. How do I do then, so that the shape property keeps the selection made and see in Qt Designer (application creation phase in MainWindow) change the shape of the Led of the svg image. How should I write the plugin code to get this effect ?

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to insert a drawing in QWidget in Qt Designer form ?

    How should I write the plugin code to get this effect ?
    The plugin code you wrote (and I built on my PC) works just fine in Qt Designer under Qt 5.15.3. In Qt Designer, I can create an LED widget, change the color and shape, and it shows up on the form in Qt Creator. I don't see any reason why the same code, built against Qt 6.x should not also work with the Qt Designer that ships with the Qt 6.x distribution.

    There seems to be something broken in your copy of Qt Creator or in the way you are building or installing the plugin. I think that the plugin is unable to load the SVG files in Qt Designer and I think it is using your icon instead of an actual LED instance. There are two ways to test this:

    1 - Change the icon and rebuild the plugin. If you see the new icon when you insert the widget in a Qt Designer form, then you know that is what is happening.

    2a - Insert a QMessageBox warning in the paintEvent where you try to load the svg file for the color and shape. If the load fails, pop up the warning.

    or

    2b - Instead of a message box, if the load fails, draw an "X" instead of rendering the svg.

    In the case of 1, it is possible that the Qt Creator cannot make the LED widget at all so is substituting the icon. That could be because you have not linked the DLL against the SVG library, so Qt Designer does not load it and cannot instantiate the SVG renderer.

    In the case of 2a, it is creating the widget but is unable to load the SVG to perform the rendering. Again, this could be a problem with the QSvg DLL.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Apr 2010
    Location
    Italia
    Posts
    149
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Thumbs up Re: How to insert a drawing in QWidget in Qt Designer form ?

    Quote Originally Posted by d_stranz View Post
    2a - Insert a QMessageBox warning in the paintEvent where you try to load the svg file for the color and shape. If the load fails, pop up the warning.
    ...
    In the case of 2a, it is creating the widget but is unable to load the SVG to perform the rendering. Again, this could be a problem with the QSvg DLL.
    I rewrote the code again and post it for you so you can see it too. I put the QMessageBox in QNewLed:aintEvent(..) at what point ?
    QNewLed.h:
    Qt Code:
    1. #pragma once
    2.  
    3. #include <QtWidgets/QWidget>
    4. #include <QtUiPlugin/QDesignerExportWidget>
    5. #include <QtSvg>
    6. #include <QSvgRenderer>
    7.  
    8. class QDESIGNER_WIDGET_EXPORT QNewLed : public QWidget
    9. {
    10. Q_OBJECT
    11.  
    12. Q_PROPERTY(ledShape shape READ getShape WRITE setShape)
    13.  
    14. public:
    15. explicit QNewLed(QWidget *parent = nullptr);
    16. virtual ~QNewLed();
    17.  
    18. enum ledShape { Circle, Square, Triangle, Rounded };
    19. Q_ENUM(ledShape)
    20.  
    21. public slots:
    22. ledShape getShape() const { return m_shape; }
    23. void setShape(ledShape);
    24.  
    25. protected:
    26. void paintEvent(QPaintEvent* event) override;
    27. ledShape m_shape;
    28. QStringList m_shapes;
    29.  
    30. private:
    31. QSvgRenderer* renderer;
    32. };
    To copy to clipboard, switch view to plain text mode 
    QNewLed.cpp:
    Qt Code:
    1. #include "QNewLed.h"
    2.  
    3. QNewLed::QNewLed(QWidget *parent) : QWidget(parent), m_shape(Rounded)
    4. {
    5. m_shapes << ":/resources/circle_green.svg" << ":/resources/square_orange.svg" << ":/resources/triang_blue.svg" << ":/resources/round_yellow.svg";
    6. setMinimumSize(QSize(50, 50));
    7. renderer = new QSvgRenderer();
    8. }
    9.  
    10. QNewLed::~QNewLed()
    11. {
    12. delete renderer;
    13. }
    14.  
    15. void QNewLed::setShape(ledShape newShape)
    16. {
    17. m_shape = newShape;
    18.  
    19. update();
    20. }
    21.  
    22. void QNewLed::paintEvent(QPaintEvent* event)
    23. {
    24. Q_UNUSED(event);
    25.  
    26. QPainter painter(this);
    27.  
    28. QString ledShapeAndColor;
    29. ledShapeAndColor = m_shapes[m_shape];
    30.  
    31. painter.setRenderHint(QPainter::Antialiasing, true);
    32.  
    33. renderer->load(ledShapeAndColor);
    34. renderer->render(&painter);
    35. }
    To copy to clipboard, switch view to plain text mode 
    QNewLedPlugin.h:
    Qt Code:
    1. #pragma once
    2.  
    3. #include <QtUiPlugin/QDesignerCustomWidgetInterface>
    4.  
    5. class QNewLedPlugin : public QObject, public QDesignerCustomWidgetInterface
    6. {
    7. Q_OBJECT
    8. Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface" FILE "qnewledplugin.json")
    9.  
    10. public:
    11. QNewLedPlugin(QObject *parent = nullptr);
    12.  
    13. bool isContainer() const override;
    14. bool isInitialized() const override;
    15. QIcon icon() const override;
    16. QString domXml() const override;
    17. QString group() const override;
    18. QString includeFile() const override;
    19. QString name() const override;
    20. QString toolTip() const override;
    21. QString whatsThis() const override;
    22. QWidget *createWidget(QWidget *parent);
    23. void initialize(QDesignerFormEditorInterface *core);
    24.  
    25. private:
    26. bool initialized;
    27. };
    To copy to clipboard, switch view to plain text mode 
    QNewLedPlugin.cpp:
    Qt Code:
    1. #include "QNewLed.h"
    2. #include "QNewLedPlugin.h"
    3.  
    4. #include <QtCore/QtPlugin>
    5.  
    6. QNewLedPlugin::QNewLedPlugin(QObject *parent) : QObject(parent)
    7. {
    8. initialized = false;
    9. }
    10.  
    11. void QNewLedPlugin::initialize(QDesignerFormEditorInterface * /*core*/)
    12. {
    13. if (initialized)
    14. return;
    15.  
    16. initialized = true;
    17. }
    18.  
    19. bool QNewLedPlugin::isInitialized() const
    20. {
    21. return initialized;
    22. }
    23.  
    24. QWidget *QNewLedPlugin::createWidget(QWidget *parent)
    25. {
    26. return new QNewLed(parent);
    27. }
    28.  
    29. QString QNewLedPlugin::name() const
    30. {
    31. return "QNewLed";
    32. }
    33.  
    34. QString QNewLedPlugin::group() const
    35. {
    36. return "I Miei Plugin";
    37. }
    38.  
    39. QIcon QNewLedPlugin::icon() const
    40. {
    41. return QIcon();
    42. }
    43.  
    44. QString QNewLedPlugin::toolTip() const
    45. {
    46. return QString();
    47. }
    48.  
    49. QString QNewLedPlugin::whatsThis() const
    50. {
    51. return QString();
    52. }
    53.  
    54. bool QNewLedPlugin::isContainer() const
    55. {
    56. return false;
    57. }
    58.  
    59. QString QNewLedPlugin::domXml() const
    60. {
    61. return "<widget class=\"QNewLed\" name=\"led\">\n"
    62. " <property name=\"geometry\">\n"
    63. " <rect>\n"
    64. " <x>0</x>\n"
    65. " <y>0</y>\n"
    66. " <width>50</width>\n"
    67. " <height>50</height>\n"
    68. " </rect>\n"
    69. " </property>\n"
    70. " <property name=\"toolTip\" >\n"
    71. " <string>Binary Led</string>\n"
    72. " </property>\n"
    73. " <property name=\"whatsThis\" >\n"
    74. " <string>Led widget</string>\n"
    75. " </property>\n"
    76. " <property name=\"shape\" >\n"
    77. " <enum>QNewLed::Circle</enum>\n"
    78. " </property>\n"
    79. "</widget>\n";
    80. }
    81.  
    82. QString QNewLedPlugin::includeFile() const
    83. {
    84. return "QNewLed.h";
    85. }
    To copy to clipboard, switch view to plain text mode 
    This new version is a little more simplified than the previous one, just to understand where I'm wrong.

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to insert a drawing in QWidget in Qt Designer form ?

    Qt Code:
    1. void QNewLed::paintEvent(QPaintEvent* event)
    2. {
    3. Q_UNUSED(event);
    4.  
    5. QPainter painter(this);
    6.  
    7. QString ledShapeAndColor;
    8. ledShapeAndColor = m_shapes[m_shape];
    9.  
    10. painter.setRenderHint(QPainter::Antialiasing, true);
    11.  
    12. if ( renderer->load(ledShapeAndColor) )
    13. renderer->render(&painter);
    14. else
    15. QMessageBox::warning( this, "Warning", "QSvgRenderer->load() failed" );
    16. }
    To copy to clipboard, switch view to plain text mode 

    But this code is very inefficient. You do not need to load the SVG file every time you paint. You need to load it only when you construct the default LED or when you change the shape or color. So in your QNewLed(), setColor(), and setShape() methods, that's where you should call renderer->load(). In the paintEvent() all you need to do is call renderer->render(). In the constructor for the QNewLed class, you should set the default color and shape and load that SVG file there.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  7. #7
    Join Date
    Apr 2010
    Location
    Italia
    Posts
    149
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to insert a drawing in QWidget in Qt Designer form ?

    I made the change I proposed in paintEvent(QPaintEvent* event). No svg image upload error message appeared. However, it is still impossible to get the new selection accepted by the shape property, which always remains in Circle.

  8. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to insert a drawing in QWidget in Qt Designer form ?

    Sorry, I can't give you any more help on this. Your code works on my PC, so I don't know what is wrong on your end. Your JSON file is empty, but it doesn't seem to matter.

    One last thing to try: Instead of rendering an SVG file, just replace the paint event code with some simple QPainter drawing. It doesn't matter what it is as long as something different is drawn for each shape. If you still don't see any changes, then I have no idea what could be wrong.

    Qt Code:
    1. void QNewLed::paintEvent( QPaintEvent * event )
    2. {
    3.  
    4. QPainter painter( this );
    5. painter.setRenderHint( QPainter::Antialiasing, true );
    6. painter.setPen( Qt::blue );
    7.  
    8. const QRect & rect = event->rect();
    9. switch m_shape :
    10. {
    11. case Circle:
    12. painter.drawEllipse( rect );
    13. break;
    14.  
    15. case Square:
    16. painter.drawRect( rect );
    17. break;
    18.  
    19. case Triangle:
    20. {
    21. QPolygon triangle = QPolygon() << rect.bottomLeft() << rect.bottomRight() << QPoint( rect.center().x(), rect.topLeft().y() );
    22. painter.drawConvexPolygon( triangle );
    23. }
    24. break;
    25.  
    26. case Rounded:
    27. {
    28. QPoint c = rect.center();
    29. QPoint p1( c.x(), rect.bottomLeft().y() );
    30. QPoint p2( rect.bottomLeft().x(), c.y() );
    31. QPoint p3( c.x(), rect.topLeft().y() );
    32. QPoint p4( rect.bottomRight().x(), c.y());
    33. QPolygon diamond = QPolygon() << p1 << p2 << p3 << p4;
    34. painter.drawConvexPolygon( diamond );
    35. }
    36. break;
    37. }
    38. }
    To copy to clipboard, switch view to plain text mode 
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Replies: 8
    Last Post: 19th September 2014, 12:16
  2. Promoting the parent QWidget of a QWidget form
    By extrakun in forum Qt Tools
    Replies: 6
    Last Post: 16th April 2010, 15:19
  3. Insert picture in a form using label
    By cwnelatury in forum Newbie
    Replies: 14
    Last Post: 19th March 2010, 00:43
  4. [Qt4.1] How to insert an image inside a Form?
    By Gonzalez in forum Qt Tools
    Replies: 5
    Last Post: 23rd September 2008, 12:20
  5. How to insert an image in background of a Form?
    By awanish_jmi in forum Qt Tools
    Replies: 2
    Last Post: 8th August 2008, 11:52

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.