Results 1 to 2 of 2

Thread: Hiding QProxyWidget in QGraphicsLinearLayout not working

  1. #1
    Join Date
    Oct 2009
    Posts
    38
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60

    Default Hiding QProxyWidget in QGraphicsLinearLayout not working

    Hi all,

    I have been working on this issue for some time now, scouring the net, and reading on this forum, but haven't yet found an answer to my issue. I have a QGraphicsLinearLayout on my QGraphicsScene with a horizontal layout, and I added a number of widgets to it that are extended from QGraphicsProxyWidget. At some point during the program, something happens that causes one of the widgets, an indicator icon, either to show or hide. My expectation for this linear layout is that it should be able to adjust the cell widths according to the stretch factors given. It doesn't. Since I have the background that the layout is sitting over set to black, whenever the icon disappears, there is a black box in its place.

    I have created a minimal version of what I am doing:

    TestClasses.h
    Qt Code:
    1. #ifndef TESTCLASSES_H
    2. #define TESTCLASSES_H
    3.  
    4. #include <QtGui>
    5.  
    6. class QGraphicsWidget;
    7. class InnerClass1;
    8. class InnerClass2;
    9.  
    10. class OuterClass : public QGraphicsWidget
    11. {
    12. Q_OBJECT
    13.  
    14. public:
    15. OuterClass(QGraphicsItem* parent = 0);
    16. virtual ~OuterClass();
    17.  
    18. void showIcon(const bool show);
    19.  
    20. public slots:
    21. void resetLayout();
    22.  
    23. protected:
    24. void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget);
    25.  
    26. private:
    27. QGraphicsLinearLayout* m_layout;
    28. InnerClass1* m_string1Widget;
    29. InnerClass1* m_string2Widget;
    30. InnerClass2* m_iconWidget;
    31. };
    32.  
    33. class InnerClass1 : public QGraphicsProxyWidget
    34. {
    35. Q_OBJECT
    36.  
    37. public:
    38. InnerClass1(QGraphicsWidget* parent = 0, const QString & string = "");
    39. ~InnerClass1();
    40.  
    41. private:
    42. QLabel *m_string;
    43.  
    44. };
    45.  
    46. class InnerClass2 : public QGraphicsProxyWidget
    47. {
    48. Q_OBJECT
    49.  
    50. public:
    51. InnerClass2(QGraphicsWidget* parent = 0);
    52. ~InnerClass2();
    53.  
    54. void showIcon(const bool show);
    55.  
    56. signals:
    57. void visibilityChanged();
    58.  
    59. protected:
    60. void timerEvent(QTimerEvent * event);
    61.  
    62. private:
    63. QLabel *m_icon;
    64. int m_width;
    65. int m_timerId;
    66.  
    67. };
    68.  
    69. #endif // TESTCLASSES_H
    To copy to clipboard, switch view to plain text mode 

    TestClasses.cpp
    Qt Code:
    1. #include "TestClasses.h"
    2. #include <QGraphicsWidget>
    3.  
    4.  
    5. /*****************************************************************************************
    6.  ** OuterClass class definitions
    7.  *****************************************************************************************/
    8.  
    9. OuterClass::OuterClass(QGraphicsItem* parent)
    10. : QGraphicsWidget(parent)
    11. {
    12. m_layout = new QGraphicsLinearLayout();
    13. m_layout->setContentsMargins(0,0,0,0);
    14. m_layout->setSpacing(0);
    15. setLayout(m_layout);
    16.  
    17. m_string1Widget = new InnerClass1(this, "First string");
    18. m_string2Widget = new InnerClass1(this, "Second string");
    19. m_iconWidget = new InnerClass2(this);
    20.  
    21. m_layout->addItem(m_string1Widget);
    22. m_layout->setStretchFactor(m_string1Widget, 2);
    23.  
    24. m_layout->addItem(m_iconWidget);
    25. m_layout->setStretchFactor(m_iconWidget, 1);
    26.  
    27. m_layout->addItem(m_string2Widget);
    28. m_layout->setStretchFactor(m_string2Widget, 2);
    29.  
    30. connect(m_iconWidget, SIGNAL(visibilityChanged()), this, SLOT(resetLayout()));
    31. }
    32.  
    33. OuterClass::~OuterClass() {
    34.  
    35. }
    36.  
    37. void OuterClass::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {
    38. Q_UNUSED(option);
    39. Q_UNUSED(widget);
    40.  
    41. painter->save();
    42. painter->setRenderHint(QPainter::Antialiasing);
    43. // First, fill rectangle with background color.
    44. painter->fillRect(boundingRect(), Qt::black);
    45. painter->restore();
    46. }
    47.  
    48. void OuterClass::resetLayout()
    49. {
    50. // NOTE: adding these didn't help
    51. //this->updateGeometry();
    52. //m_layout->updateGeometry();
    53. m_layout->invalidate();
    54. m_layout->activate();
    55. }
    56.  
    57.  
    58. /*****************************************************************************************
    59.  ** InnerClass1 class definitions
    60.  *****************************************************************************************/
    61.  
    62. InnerClass1::InnerClass1(QGraphicsWidget* parent, const QString & string)
    63. : QGraphicsProxyWidget(parent)
    64. {
    65. m_string = new QLabel();
    66. m_string->setText(string);
    67. QStyle* style = m_string->style();
    68. style->visualAlignment(Qt::LayoutDirectionAuto, Qt::AlignCenter);
    69. this->setWidget(m_string);
    70. }
    71.  
    72. InnerClass1::~InnerClass1()
    73. {
    74. }
    75.  
    76.  
    77. /*****************************************************************************************
    78.  ** InnerClass2 class definitions
    79.  *****************************************************************************************/
    80.  
    81. static const QString ICON_SRC = ":/circle.png";
    82.  
    83. InnerClass2::InnerClass2(QGraphicsWidget* parent)
    84. : QGraphicsProxyWidget(parent)
    85. {
    86. QPixmap pixmap(ICON_SRC);
    87. m_icon = new QLabel();
    88. m_icon->setPixmap(pixmap);
    89. this->setWidget(m_icon);
    90. m_width = m_icon->rect().width();
    91. m_timerId = startTimer(1000);
    92. }
    93.  
    94. InnerClass2::~InnerClass2()
    95. {
    96. }
    97.  
    98. void InnerClass2::timerEvent(QTimerEvent * event)
    99. {
    100. if (event->timerId() == m_timerId)
    101. showIcon(!m_icon->isVisible());
    102. }
    103.  
    104. void InnerClass2::showIcon(bool show)
    105. {
    106. if (m_icon->isVisible() != show) {
    107. m_icon->setVisible(show);
    108. // adjust the icon geometry and tell the layout to reset itself
    109. QRect rect = m_icon->rect();
    110. if (show)
    111. rect.setWidth(m_width);
    112. else
    113. rect.setWidth(0);
    114. // NOTE: adding this didn't help
    115. //m_icon->setGeometry(rect);
    116. this->setGeometry(rect);
    117. emit visibilityChanged();
    118. }
    119. }
    To copy to clipboard, switch view to plain text mode 

    and I instantiate this from MainWindow.h:
    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3. #include "TestClasses.h"
    4. #include <QGraphicsView>
    5.  
    6. MainWindow::MainWindow(QWidget *parent) :
    7. QMainWindow(parent),
    8. ui(new Ui::MainWindow)
    9. {
    10. ui->setupUi(this);
    11. OuterClass *outer = new OuterClass();
    12. m_scene = new QGraphicsScene(outer->rect());
    13. m_scene->addItem(outer);
    14.  
    15. QGraphicsView *view = new QGraphicsView(m_scene);
    16. this->setCentralWidget(view);
    17. }
    18.  
    19. MainWindow::~MainWindow()
    20. {
    21. delete ui;
    22. }
    To copy to clipboard, switch view to plain text mode 

    You could use any .png file, but I'm using the one from the Qt examples directory found at widgets/tooltips/images/circle.png.

    In the OuterClass constructor, I create three widgets, two strings and one icon. I place then into the layout with the icon as the second in line. I give the two string widgets greater priority for stretching with a factor of 2 for each. I give the icon widget less with a factor of 1. Then I connect the signal from the icon widget to a slot belonging to OuterClass.

    InnerClass1, the string class, sets the string into its QLabel. InnerClass2, the icon class, sets the pixmap and a timer for 1 second intervals. When the timer goes off, InnerClass2's timerEvent() calls showIcon() to toggle the icon visibility, and showIcon() emits the signal that was connected to by OuterClass. The OuterClass slot then calls invalidate() and activate() on the layout. I also tried adding a call to updateGeometry() for both the QLabel icon object and the icon widget itself.

    From everything I've heard and read, this should cause the layout to reset itself, but if you grab my code and run it with some icon, you'll see that the text cells don't get allocated more space to cover over the icon's area, and then less space to make room for the icon again, but rather the black background is being shown. I even went to the extent of having InnerClass2::showIcon() reset the InnerClass2 rect to have the width of the icon when it is to be show, and 0 when it is not to be shown. I set the icon widget's geometry with this rect, and even tried setting the QLabel for icon as well with this rect. This didn't help.

  2. #2
    Join Date
    Oct 2009
    Posts
    38
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60

    Default Re: Hiding QProxyWidget in QGraphicsLinearLayout not working

    So I guess no one has any good ideas here. I have fixed my issue, but it seems kind of a kludge. Instead of calling invalidate() and then activate() on the layout, I am removing the widget and hiding it when I want it not shown, and then I am adding it and showing it when I want it shown. This works, but I am still stumped as to why my other implementation didn't.

Similar Threads

  1. Calculate scene coordinates from QGraphicsLinearLayout
    By onurozcelik in forum Qt Programming
    Replies: 2
    Last Post: 21st January 2011, 08:38
  2. QProxyWidget and My Scene
    By salmanmanekia in forum Newbie
    Replies: 3
    Last Post: 2nd June 2010, 07:56
  3. QGraphicsLinearLayout does not behave like QVBoxLayout
    By jobrandt in forum Qt Programming
    Replies: 3
    Last Post: 7th September 2009, 09:59
  4. QGraphicsLinearLayout
    By bunjee in forum Qt Programming
    Replies: 0
    Last Post: 8th February 2009, 14:31
  5. Issue with QGraphicsLinearLayout (Qt-4.4 snapshot)
    By momesana in forum Qt Programming
    Replies: 3
    Last Post: 10th January 2008, 02:05

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.