Results 1 to 11 of 11

Thread: Painting problem

  1. #1
    Join Date
    May 2007
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Painting problem

    I'm new to C++ and Qt. I've been trying to port some code from an app
    using Qt 3 to Qt 4. I'm currently using Ubuntu and Qt 4.2.3. The code
    below runs under Qt 3, but not Qt 4. The problem occurs in the drawPBS
    method in the Main_Widget class when trying to paint pbs. All I get is the error message:
    "QPainter::begin: Widget painting can only begin as a result of a
    paintEvent."

    I'm sure I'm missing something fundamental, but just haven't been able
    to find it. Any pointers (no pun intended) would be greatly
    appreciated.

    This is my first post, so if I've sent too much information, let me
    know.

    Cheers, Mel

    Code follows:
    .................................................. ..................
    Qt Code:
    1. #include <qapplication.h>
    2. #include <qfontdatabase.h>
    3. #include "main_widget.h"
    4.  
    5.  
    6. int main (int argc, char **argv)
    7. {
    8. QApplication app(argc, argv);
    9. Main_Widget *w = new Main_Widget;;
    10. app.setStyleSheet("QFrame {border : 1px solid rgb(255,200,55)}");
    11. w->show();
    12. return app.exec();
    13. }
    14. #ifndef SDXCVR_MAINWIDGET_H
    15. #define SDXCVR_MAINWIDGET_H
    16.  
    17. #include <qwidget.h>
    18. #include <qapplication.h>
    19. #include <qfont.h>
    20. #include <qlistview.h>
    21. #include <QLabel>
    22. #include <qfile.h>
    23. #include <qpainter.h>
    24. #include <QPaintDevice>
    25. #include <qimage.h>
    26. #include <qdir.h>
    27. #include <QKeyEvent>
    28. #include <QMouseEvent>
    29. #include <QPalette>
    30. #include <QFrame>
    31.  
    32. #include "pbs.h"
    33. #include "sm.h"
    34.  
    35. class Main_Widget : public QWidget
    36. {
    37.  
    38.  
    39. Q_OBJECT
    40.  
    41. private:
    42.  
    43. Sm *sm;
    44. PBS *pbs;
    45. QFrame *sFrame;
    46.  
    47. void updateLayout();
    48. void drawPBS();
    49.  
    50. public:
    51. Main_Widget(QWidget *parent = 0);
    52.  
    53. protected:
    54.  
    55. void paintEvent( QPaintEvent * );
    56.  
    57.  
    58. };
    59. #endif
    60.  
    61. #include "main_widget.h"
    62.  
    63. Main_Widget::Main_Widget(QWidget *parent)
    64. : QWidget(parent)
    65. {
    66.  
    67. setFocusPolicy( Qt::TabFocus );
    68. setPalette(QPalette(QColor(0, 0, 0)));
    69. setAutoFillBackground(true);
    70. setMinimumWidth( 650 );
    71. setMinimumHeight( 300 );
    72.  
    73. setWindowTitle(" Test " );
    74.  
    75. // sFrame
    76.  
    77. sFrame = new QFrame( this );
    78. sFrame->setFrameStyle( QFrame::StyledPanel | QFrame::Plain );
    79.  
    80. // sm
    81. sm = new Sm( sFrame );
    82. sm->setPalette(QColor(20, 20, 50) );
    83. sm->setAutoFillBackground(true);
    84.  
    85. // PBS
    86. pbs = new PBS( sFrame );
    87. QPalette r(pbs->palette());
    88. r.setColor(QPalette::Background, QColor(100, 0, 0));
    89. pbs->setPalette(r);
    90. pbs->setAutoFillBackground(true);
    91.  
    92. }
    93.  
    94. void Main_Widget::paintEvent( QPaintEvent * )
    95. {
    96. printf("paintEvent() \n");
    97.  
    98. updateLayout();
    99. drawPBS();
    100.  
    101. }
    102.  
    103. void Main_Widget::updateLayout()
    104. {
    105. printf("updateLayout() \n");
    106.  
    107. sFrame->setGeometry(
    108. 1,
    109. 35,
    110. width() - 2,
    111. height() - 18 - 36 );
    112.  
    113. sm->setGeometry(
    114. 2,
    115. 2,
    116. sFrame->width() - 4,
    117. sFrame->height() - 4 - 120 - 15 );
    118.  
    119. pbs->setGeometry(
    120. 2,
    121. sm->height() + 2,
    122. sFrame->width() - 4,
    123. 15 );
    124. printf("updateLayout() pbs Geometry \n");
    125. printf(" 2, %d, %d, 15\n", sm->height() + 2, sFrame->width() - 4);
    126. }
    127.  
    128.  
    129.  
    130. void Main_Widget::drawPBS()
    131. {
    132.  
    133. p.begin(pbs);
    134. p.eraseRect( 0, 0, pbs->width(), pbs->height() );
    135. p.setPen( Qt::yellow );
    136. p.drawLine(252, 50, 252, 190);
    137. p.drawLine(4,115,70,115);
    138. p.end();
    139.  
    140. }
    141. #ifndef SDXCVR_PBS_H
    142. #define SDXCVR_PBS_H
    143.  
    144. #include <qwidget.h>
    145. #include <QMouseEvent>
    146. #include <QPainter>
    147. #include <QPaintDevice>
    148.  
    149.  
    150. class PBS : public QWidget
    151. {
    152. Q_OBJECT
    153.  
    154. public:
    155.  
    156. PBS(QWidget *parent = 0);
    157.  
    158. private:
    159. int x0;
    160.  
    161. protected:
    162. void mousePressEvent( QMouseEvent * );
    163. void mouseMoveEvent( QMouseEvent * );
    164.  
    165. signals:
    166. void set_lower_pb( int );
    167. void set_upper_pb( int );
    168. void movement( int );
    169. };
    170. #endif
    171.  
    172. #include "pbs.h"
    173. #include "main_widget.h"
    174.  
    175. PBS::PBS(QWidget *parent) : QWidget(parent)
    176. {
    177. setMouseTracking( true );
    178. }
    179.  
    180. void PBS::mouseMoveEvent( QMouseEvent *e )
    181. {
    182. emit movement( e->x() );
    183. }
    184.  
    185. void PBS::mousePressEvent( QMouseEvent *e )
    186. {
    187. x0 = e->x();
    188.  
    189. if ( e->button() == Qt::LeftButton )
    190. emit set_lower_pb( x0 );
    191. if ( e->button() == Qt::RightButton )
    192. emit set_upper_pb( x0 );
    193. }
    194. #ifndef SDXCVR_SM_H
    195. #define SDXCVR_SM_H
    196.  
    197. #include <qwidget.h>
    198. #include <QMouseEvent>
    199.  
    200. class Sm : public QWidget
    201. {
    202. Q_OBJECT
    203.  
    204. public:
    205. ;
    206. Sm(QWidget *parent = 0);
    207. private:
    208. int mouseMoving;
    209.  
    210. protected:
    211. void mouseReleaseEvent( QMouseEvent * );
    212. void mouseMoveEvent( QMouseEvent * );
    213.  
    214. signals:
    215. void tune1( int );
    216. void tune2( int );
    217. void plot( int );
    218. void movement( int );
    219. };
    220. #endif
    221. #ifndef SDXCVR_SM_H
    222. #define SDXCVR_SM_H
    223.  
    224. #include "sm.h"
    225.  
    226.  
    227. Sm::Sm(QWidget *parent) : QWidget(parent)
    228. {
    229. //setMouseTracking( true );
    230.  
    231. mouseMoving = 0;
    232. }
    233.  
    234. void Sm::mouseReleaseEvent( QMouseEvent *e )
    235. {
    236. if ( !mouseMoving && e->button() == Qt::LeftButton )
    237. emit tune1( e->x() );
    238.  
    239. if ( !mouseMoving && e->button() == Qt::RightButton )
    240. emit plot( e->y() );
    241.  
    242. mouseMoving = false;
    243. }
    244.  
    245. void Sm::mouseMoveEvent( QMouseEvent *e )
    246. {
    247. static int x0 = 0;
    248. int output;
    249.  
    250. mouseMoving = true;
    251.  
    252. if ( x0 - e->x() >= 0 )
    253. output = 1;
    254. else
    255. output = -1;
    256.  
    257. if ( e->button() == Qt::LeftButton )
    258. emit tune2( output );
    259. else if ( e->button() == Qt::RightButton )
    260. emit tune2( output * 10 );
    261. else if ( e->button() == Qt::MidButton )
    262. emit tune2( output * 100 );
    263. else
    264. emit movement( e->x() );
    265.  
    266. x0 = e->x();
    267. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by high_flyer; 8th May 2007 at 16:13. Reason: missing [code] tags

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Painting problem

    The code
    below runs under Qt 3, but not Qt 4. The problem occurs in the drawPBS
    method in the Main_Widget class when trying to paint pbs.
    I am surprised it compiles at all!
    Mixing Qt3 and Qt4 is BAD!
    Specially when dealing with painting, since painting (among other things) has been drastically changed in Qt4, one of the changes is that painting in Qt4 is only done in paintEvent() - which will explain the error you are getting.

    You should port your code to Qt4 - proper!

  3. #3
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Painting problem

    You have a big problem here:
    You're trying to paint on a widget from another widget. This will never work in Qt4( did it really work in 3? ).

    Why don't you move the code from Main_widget:aintEvent in PBS:aintEvent()? It should be no problem, practically the coordinates will be the same.


    Another issue is updateLayout. You shouldn't reposition widgets in a paint event (don't you get any flicker? ). Instead you should move them in mouseMoveEvent(), and let them paint themselves.

    To do this you have a "little" redesigning to do. Anyway, once you get started, you can ask here if you run in any trouble. But you really should rewrite.

    Regards

  4. #4
    Join Date
    May 2007
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Painting problem

    Thanks to all for the replies.

    The code is compiled in Qt 4 only.

    Marcel,

    I had actually created a paintEvent in the PBS class before posting my question, but it didn't work either. The code is below. Nothing is painted when this event is called either, but at least I don't get the original error message. The program I'm trying to port works quite nicely in Qt 3, and displays both spectrum and waterfall displays. I've never noticed any flickering. I have no problems with rewriting some of the code, if I can ever get the painting problem solved. Seems like I'm still missing something here ...

    Note that nothing is painted anywhere on the screen when the paintEvent in PBS is executed.

    Code follows ....................................

    #include "pbs.h"
    #include "main_widget.h"

    PBS::PBS(QWidget *parent) : QWidget(parent)
    {
    setMouseTracking( true );
    }

    void PBS::mouseMoveEvent( QMouseEvent *e )
    {
    emit movement( e->x() );
    }

    void PBS::mousePressEvent( QMouseEvent *e )
    {
    x0 = e->x();

    if ( e->button() == Qt::LeftButton )
    emit set_lower_pb( x0 );
    if ( e->button() == Qt::RightButton )
    emit set_upper_pb( x0 );
    }
    void PBS:aintEvent( QPaintEvent * )
    {
    printf("PBS paintEvent() \n");

    QPainter p;
    p.begin(this);
    // p.eraseRect( 0, 0, this->width(), this->height() );
    p.setPen( Qt::yellow );
    p.drawLine(252, 50, 252, 190);
    p.drawLine(4,115,34,115);
    p.end();


    }

  5. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Painting problem

    Yes, I believe you don't see anything on the screen
    This is because you are painting off-widget... You first must take a look at what rect() returns and draw everything relative to rect().topLeft and such that everything will fit in the widget rect.

    My guess is that your widget(PBS, possibly the others) doesn't have a minimum size. You should reimplement minimumSize and sizeHint to return the minimum size and the preferred size for your widget(s).

    Or, if you know these sizes, you can just set them in the widget constructor. Not setting them, your widget will have a size of (-1, -1).

    What errors did you get?

    Try getting the code between CODE tags, because it is very hard top read as simple text.


    regards

  6. #6
    Join Date
    May 2007
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Painting problem

    Marcel,

    Thanks for your patience.

    I get no errors when running the last piece of code I sent; it just doesn't paint. I printed out this->width() and this->height just before the call to eraseRect, and it shows the size of pbs to be (2, 109, 644, 15). I removed the line that was clearly out of the print area, compiled, and ran it again. Still no painting.

    WRT the size of the widgets, I would think that's set in updateLayout(). I didn't write the original code, so I'm not sure why the author chose to implement it that way.

    I'll have many changes in arithmetic to make in the program, but I feel that if I can get the toy I posted to run I'll be able to conquer the rest.

    Thanks.

    Cheers,
    Mel

  7. #7
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Painting problem

    Instead of drawing the lines try p.fillRect( rect(), Qt::red ) ;
    See if anything is being painted now. Perhaps you need to set a width for the pen.

    regards

  8. #8
    Join Date
    May 2007
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Painting problem

    Marcel,

    p.fillRect( rect(), Qt::red ) ;

    filled pbs with a bright red.

    The pen width is set to 0, so a 1 pixel width line should be drawn.

    I removed the background from pbs, but still no line.

    Thus far the only thing I've been able to display on pbs is your fillRect suggestion.
    I also tried
    p.fillRect(4,115,34,6,Qt::red);
    which should have filled a small rectangle, but nothing happened.

    It's probably late in your area, but do you have any last suggestions for today?

    Thanks again.

    Cheers,
    Mel

  9. #9
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Painting problem

    OK.
    A painter draws in paint device (widget in this case ) local coordinates.
    Meaning that when you used my previous suggestion, something got filled, but not the right thing .

    Thus, everything must be drawn relative to (0,0).
    Calling p.fillRect( 0, 0, size().width(), size().height(), Qt:red ) will fill the ENTIRE widget.
    For what you were trying to achieve call p.fillRect( 0, 0, 30, 6, Qt:red ). This will fill a small rect in the top left corner of the widget.

    To be sure just do a drawRect( 0, 0, size().width(), size().height() ) - draw a frame around the widget.

    If this works ( and it will ), draw everything relative to (0, 0 ) - lines, etc.

    It's probably late in your area, but do you have any last suggestions for today?
    It's 11 PM, not so late.

    Regards

  10. #10
    Join Date
    May 2007
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Painting problem

    Sigh ... Of course it's relative! I knew there was some fundamental point I was missing! I adjusted my numbers, and painted the rectangle and the line I was trying to paint.

    I can't thank you enough for your help, Marcel. I have a lot of work still ahead, but your help has removed a big roadblock. I put my question out to this group, because they had advertised a 95% success rate in solving users' problems. Mine can certainly be added to the success list thanks to your efforts.

    Thanks again for your time and patience.

    Cheers,
    Mel

  11. #11
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Painting problem

    Happy to be of some help!

    Regards

Similar Threads

  1. Painting problem
    By ScoOteR in forum Qt Programming
    Replies: 5
    Last Post: 11th March 2007, 11:03
  2. Painting Problem
    By shyam prasad in forum Qt Programming
    Replies: 3
    Last Post: 5th February 2007, 14:07
  3. QTimer problem ... it runs but never triggs
    By yellowmat in forum Newbie
    Replies: 4
    Last Post: 4th July 2006, 12:54
  4. Problem with bitBlt
    By yellowmat in forum Newbie
    Replies: 1
    Last Post: 5th April 2006, 14:08
  5. Replies: 16
    Last Post: 7th March 2006, 15:57

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.