Results 1 to 11 of 11

Thread: State machine inside a QWidget

  1. #1
    Join Date
    Apr 2010
    Location
    Porto Alegre, RS, Brazil
    Posts
    37
    Thanks
    9
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Question State machine inside a QWidget

    Hi everyone,

    I have a project that is entirely "based on QWidget". Now, I need to add a simple animation to change automatically (based on an user interaction) the styleSheet of a sub-component (a small toolbar with 3 buttons, built in the QT Creator designer).
    Since I have only 2 possible states, I though about creating a state machine to do the switching. However, on the Demo "states" (Animation Framework->States), it uses a QGraphicsView. If I would use QGraphicsView, I'd have to change almost all of my classes (yeah, bad code design, I know...).
    So, my question is, can I have a QStateMachine animation in a QWidget?

    thanks for any help

  2. #2
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: State machine inside a QWidget

    For such a simple task I would use animation direct without states, but you can use a state machine with widgets. They do not depend on the graphics view. In the detailed description of QStateMachine you have a simple example with a button.

  3. The following user says thank you to Lykurg for this useful post:

    leoalvesmachado (3rd August 2010)

  4. #3
    Join Date
    Apr 2010
    Location
    Porto Alegre, RS, Brazil
    Posts
    37
    Thanks
    9
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: State machine inside a QWidget

    Thanks a lot, Lykurg
    As you may notice, I'm just starting with qt. How would you do it using animation direct? Do you have any example?
    I've tryed before using QPropertyAnimation, but I got compiler error - seems that an ui component created by QT creator design is not a QObject... That's why I though of using stateMachines.

    I got this:
    Qt Code:
    1. QPropertyAnimation::QPropertyAnimation(QObject *, const QByteArray &, QObject *) : cannot convert parameter 1 from 'Ui::TopBar *' to 'QObject *"
    To copy to clipboard, switch view to plain text mode 

  5. #4
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: State machine inside a QWidget

    Quote Originally Posted by leoalvesmachado View Post
    seems that an ui component created by QT creator design is not a QObject...
    Well they are QObjects, but it seems you used your own "TopBar". Make sure this class has the Q_OBJECT macro. Also please show us the line, which causes the error.

  6. #5
    Join Date
    Apr 2010
    Location
    Porto Alegre, RS, Brazil
    Posts
    37
    Thanks
    9
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: State machine inside a QWidget

    The thing is, the definition of the TopBar was automatically generated by the QT Creator UI design. It does not have a single line in cpp. The component was supposed to be a QWidget (at least that was my intention). Here is its xml:
    Qt Code:
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <ui version="4.0">
    3. <class>TopBar</class>
    4. <widget class="QWidget" name="TopBar">
    5. <property name="geometry">
    6. <rect>
    7. <x>0</x>
    8. <y>0</y>
    9. <width>360</width>
    10. <height>70</height>
    11. </rect>
    12. </property>
    13. <property name="minimumSize">
    14. <size>
    15. <width>360</width>
    16. <height>70</height>
    17. </size>
    18. </property>
    19. <property name="maximumSize">
    20. <size>
    21. <width>360</width>
    22. <height>70</height>
    23. </size>
    24. </property>
    25. <property name="windowTitle">
    26. <string>Form</string>
    27. </property>
    28. <property name="autoFillBackground">
    29. <bool>false</bool>
    30. </property>
    31. <property name="styleSheet">
    32. <string notr="true">#TopBar{
    33. background-image: url(:/tbskin.png);
    34. background-repeat: no-repeat;
    35. background-color: rgba(255, 255, 255, 0);
    36. }</string>
    37. </property>
    38. <widget class="QWidget" name="verticalLayoutWidget">
    39. <property name="geometry">
    40. <rect>
    41. <x>0</x>
    42. <y>15</y>
    43. <width>371</width>
    44. <height>61</height>
    45. </rect>
    46. </property>
    47. <layout class="QVBoxLayout" name="vertical_layout">
    48. <property name="sizeConstraint">
    49. <enum>QLayout::SetFixedSize</enum>
    50. </property>
    51. <item>
    52. <layout class="QHBoxLayout" name="tb_layout">
    53. <item>
    54. <spacer name="horizontalSpacer">
    55. <property name="orientation">
    56. <enum>Qt::Horizontal</enum>
    57. </property>
    58. <property name="sizeType">
    59. <enum>QSizePolicy::Fixed</enum>
    60. </property>
    61. <property name="sizeHint" stdset="0">
    62. <size>
    63. <width>23</width>
    64. <height>20</height>
    65. </size>
    66. </property>
    67. </spacer>
    68. </item>
    69. <item>
    70. <widget class="QPushButton" name="tb_bEtc">
    71. <property name="sizePolicy">
    72. <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
    73. <horstretch>42</horstretch>
    74. <verstretch>43</verstretch>
    75. </sizepolicy>
    76. </property>
    77. <property name="minimumSize">
    78. <size>
    79. <width>42</width>
    80. <height>43</height>
    81. </size>
    82. </property>
    83. <property name="maximumSize">
    84. <size>
    85. <width>42</width>
    86. <height>43</height>
    87. </size>
    88. </property>
    89. <property name="styleSheet">
    90. <string notr="true">#tb_bEtc:!pressed:!hover {
    91. background-image: url(:/betc_normal.png);
    92. background-repeat: no-repeat;
    93. background-color: rgba(255, 255, 255, 0);
    94. border:0px;
    95. }
    96.  
    97. #tb_bEtc:pressed {
    98. background-image: url(:/betc_press.png);
    99. background-repeat: no-repeat;
    100. background-color: rgba(255, 255, 255, 0);
    101. border:0px;
    102. }
    103.  
    104. #tb_bEtc:hover:!pressed {
    105. background-image: url(:/betc_hover.png);
    106. background-repeat: no-repeat;
    107. background-color: rgba(255, 255, 255, 0);
    108. border:0px;
    109. }</string>
    110. </property>
    111. <property name="text">
    112. <string/>
    113. </property>
    114. </widget>
    115. </item>
    116. <item>
    117. <spacer name="hspcr_etc_pin">
    118. <property name="orientation">
    119. <enum>Qt::Horizontal</enum>
    120. </property>
    121. <property name="sizeType">
    122. <enum>QSizePolicy::Expanding</enum>
    123. </property>
    124. <property name="sizeHint" stdset="0">
    125. <size>
    126. <width>60</width>
    127. <height>20</height>
    128. </size>
    129. </property>
    130. </spacer>
    131. </item>
    132. <item>
    133. <widget class="QPushButton" name="tb_bPin">
    134. <property name="sizePolicy">
    135. <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
    136. <horstretch>42</horstretch>
    137. <verstretch>43</verstretch>
    138. </sizepolicy>
    139. </property>
    140. <property name="minimumSize">
    141. <size>
    142. <width>42</width>
    143. <height>43</height>
    144. </size>
    145. </property>
    146. <property name="maximumSize">
    147. <size>
    148. <width>42</width>
    149. <height>43</height>
    150. </size>
    151. </property>
    152. <property name="styleSheet">
    153. <string notr="true">#tb_bPin:!pressed:!hover {
    154. background-image: url(:/bpin_normal.png);
    155. background-repeat: no-repeat;
    156. background-color: rgba(255, 255, 255, 0);
    157. border:0px;
    158. }
    159.  
    160. #tb_bPin:pressed {
    161. background-image: url(:/bpin_press.png);
    162. background-repeat: no-repeat;
    163. background-color: rgba(255, 255, 255, 0);
    164. border:0px;
    165. }
    166.  
    167. #tb_bPin:hover:!pressed {
    168. background-image: url(:/bpin_hover.png);
    169. background-repeat: no-repeat;
    170. background-color: rgba(255, 255, 255, 0);
    171. border:0px;
    172. }</string>
    173. </property>
    174. <property name="text">
    175. <string/>
    176. </property>
    177. </widget>
    178. </item>
    179. <item>
    180. <spacer name="hspcr_pin_cls">
    181. <property name="orientation">
    182. <enum>Qt::Horizontal</enum>
    183. </property>
    184. <property name="sizeType">
    185. <enum>QSizePolicy::Expanding</enum>
    186. </property>
    187. <property name="sizeHint" stdset="0">
    188. <size>
    189. <width>60</width>
    190. <height>20</height>
    191. </size>
    192. </property>
    193. </spacer>
    194. </item>
    195. <item>
    196. <widget class="QPushButton" name="tb_bCls">
    197. <property name="sizePolicy">
    198. <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
    199. <horstretch>42</horstretch>
    200. <verstretch>43</verstretch>
    201. </sizepolicy>
    202. </property>
    203. <property name="minimumSize">
    204. <size>
    205. <width>42</width>
    206. <height>43</height>
    207. </size>
    208. </property>
    209. <property name="maximumSize">
    210. <size>
    211. <width>42</width>
    212. <height>43</height>
    213. </size>
    214. </property>
    215. <property name="styleSheet">
    216. <string notr="true">#tb_bCls:!pressed:!hover {
    217. background-image: url(:/bcls_normal.png);
    218. background-repeat: no-repeat;
    219. background-color: rgba(255, 255, 255, 0);
    220. border:0px;
    221. }
    222.  
    223. #tb_bCls:pressed {
    224. background-image: url(:/bcls_press.png);
    225. background-repeat: no-repeat;
    226. background-color: rgba(255, 255, 255, 0);
    227. border:0px;
    228. }
    229.  
    230. #tb_bCls:hover:!pressed {
    231. background-image: url(:/bcls_hover.png);
    232. background-repeat: no-repeat;
    233. background-color: rgba(255, 255, 255, 0);
    234. border:0px;
    235. }</string>
    236. </property>
    237. <property name="text">
    238. <string/>
    239. </property>
    240. </widget>
    241. </item>
    242. <item>
    243. <spacer name="horizontalSpacer_2">
    244. <property name="orientation">
    245. <enum>Qt::Horizontal</enum>
    246. </property>
    247. <property name="sizeType">
    248. <enum>QSizePolicy::Fixed</enum>
    249. </property>
    250. <property name="sizeHint" stdset="0">
    251. <size>
    252. <width>20</width>
    253. <height>20</height>
    254. </size>
    255. </property>
    256. </spacer>
    257. </item>
    258. </layout>
    259. </item>
    260. </layout>
    261. </widget>
    262. </widget>
    263. <resources/>
    264. <connections/>
    265. </ui>
    To copy to clipboard, switch view to plain text mode 

    Is there anything I can do to make it a "Q_OBJECT"? Or should I rewrite the component in cpp, so I could easily "make it a Q_OBJECT"?

  7. #6
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: State machine inside a QWidget

    Your ui file is converted to a QObject, so still valid:
    Quote Originally Posted by Lykurg View Post
    Also please show us the line, which causes the error.
    Means the part where you set up your state machine (= the lines which throw the error)

  8. #7
    Join Date
    Apr 2010
    Location
    Porto Alegre, RS, Brazil
    Posts
    37
    Thanks
    9
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: State machine inside a QWidget

    Sorry, I forgot to add the line in the last code.
    I'm not trying to use the state machine right know. Since you said you would use animation direct, I'm trying to use the QPropertyAnimation class.
    I define my TopBar as a private property of a class that inherits QWidget, using the code below:
    Qt Code:
    1. namespace Ui {
    2. class TopBar;
    3. }
    4. /**...class code...*/
    5. private:
    6. Ui::TopBar *chrome;
    To copy to clipboard, switch view to plain text mode 
    I initialize it in the constructor doing this:
    Qt Code:
    1. QWidget* activeChromeWidget = new QWidget();
    2. chrome->setupUi (activeChromeWidget);
    To copy to clipboard, switch view to plain text mode 
    I did not connect the buttons' signals to slots yet, so that's pretty much everything I do to initialize the TopBar. I get the compiler error in the animation code, at this method:
    Qt Code:
    1. void WebWidget::setChromeStyleSheet(bool active) {
    2. QString activeStyle = "#TopBar{\n background-image: url(:/tbskin.png);\n background-repeat: no-repeat;\n background-color: rgba(255, 255, 255, 0);\n}";
    3. QString inactiveStyle = "#InactiveTopBar{\n background-image: url(:/tbskin_inactive.png);\n background-repeat: no-repeat;\n background-color: rgba(255, 255, 255, 0);\n}";
    4. if (!active) {
    5. QPropertyAnimation *anim = new QPropertyAnimation(chrome, "styleSheets"); //HERE I GET ONE COMPILER ERROR
    6. anim->setDuration(2);
    7. anim->setStartValue(activeStyle); //could not reach chrome->styleSheets value here, seems to be not accessible, using the actual value
    8. anim->setEndValue(inactiveStyle);
    9. anim->start();
    10. } else {
    11. QPropertyAnimation *anim = new QPropertyAnimation(chrome, "styleSheets"); //HERE I GET ANOTHER ONE COMPILER ERROR
    12. anim->setDuration(2);
    13. anim->setStartValue(inactiveStyle); //could not reach chrome->styleSheets value here, seems to be not accessible, using the actual value
    14. anim->setEndValue(activeStyle);
    15. anim->start();
    16. }
    17. }
    To copy to clipboard, switch view to plain text mode 

    Thanks for your attention

  9. #8
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: State machine inside a QWidget

    Ok, I see. You have to use activeChromeWidget, the widget you initialized with your ui file. The ui handler is only to set up widgets.

    Also, there is a huge page about using ui files in the docs: Using a Designer UI File in Your Application. I prefer the "The Single Inheritance Approach" (with ui on heap, like the creator does). Have a look on it. It saves you doing such mistakes you did.

    EDIT: Also consider QAbstractAnimation:eleteWhenStopped for starting your animation. The code right now creates memory leaks!
    Last edited by Lykurg; 4th August 2010 at 17:04. Reason: updated contents

  10. #9
    Join Date
    Apr 2010
    Location
    Porto Alegre, RS, Brazil
    Posts
    37
    Thanks
    9
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: State machine inside a QWidget

    Thanks a lot, Lykurg, you've been very helpful. I don't have compiler errors anymore on this part.
    However, now the animation is not doing what I expect, that is change the background image from the component. Is it not allowed? Do I need to do something else here?

    by the way, I've changed the string with the name of the property styleSheets to styleSheet. There was a warning about this....
    Last edited by leoalvesmachado; 4th August 2010 at 17:54. Reason: updated contents

  11. #10
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: State machine inside a QWidget

    Ok, I haven't looked closely on what you are doing with the animation. But a animation for changing a stylesheet is nonsense. What do you expect. It only can change from one state into the other. Therefore you don't need a animation, because there is nothing to animate. In that particular case just do something like:
    Qt Code:
    1. // m_currentState is a private member
    2. void Foo::changeTabBar() {
    3. if (1 == m_currentState)
    4. {
    5. activeChromeWidget->setStyleSheet(...);
    6. m_currentState = 0;
    7. }
    8. else
    9. {
    10. activeChromeWidget->setStyleSheet(...);
    11. m_currentState = 1;
    12. }
    13. }
    To copy to clipboard, switch view to plain text mode 

    Animation is for changing the geometry, fading color etc.

  12. The following user says thank you to Lykurg for this useful post:

    leoalvesmachado (4th August 2010)

  13. #11
    Join Date
    Apr 2010
    Location
    Porto Alegre, RS, Brazil
    Posts
    37
    Thanks
    9
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: State machine inside a QWidget

    I worked...
    As usual, I was making simple things complicated
    Thanks

Similar Threads

  1. State machine implementation
    By yyiu002 in forum Qt Programming
    Replies: 1
    Last Post: 28th June 2010, 04:57
  2. How to get this Qt state machine to work?
    By blukske in forum Qt Programming
    Replies: 0
    Last Post: 1st April 2010, 10:15
  3. How to design a state machine in face of non-blocking I/O?
    By piotr.dobrogost in forum Qt Programming
    Replies: 26
    Last Post: 14th August 2009, 19:48
  4. Qt State Machine Examples don't compile
    By vitalyx in forum Newbie
    Replies: 0
    Last Post: 4th April 2009, 14:19
  5. running an app inside QWidget ?
    By drake1983 in forum Newbie
    Replies: 2
    Last Post: 14th March 2008, 15:33

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.