Results 1 to 9 of 9

Thread: Cursor not visible

  1. #1
    Join Date
    Jul 2006
    Location
    Catalunya - Spain
    Posts
    117
    Thanks
    16
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Unhappy Cursor not visible

    Hi all,

    I'm working on a Programming Framework that hides GUI fighting to programmer, that only has to center his efforts into "Business Objects". As a part of the framework there is a forms hierarchy that controls user input.

    I've an undesired behaviour on aQLineEdit. This is the scenario :

    I've a form ( derived from QDialog ) containing some widgets ( QLineEdit, QComboBox, etc. ). I have all the control about tab order ( in few words, I'm ignoring tab order ). Every "FocusOut" Event, I calculate wich is the next widget to get the focus.

    This is necessary, because every time I receive a FocusOut event, I perform data validation ( programmer's Business Objects should do the work ) and if validation is OK, I step to the next widget, else I retain user input to the last widget. Also Business Object can activate / deactivate widgets depending on the values introduced by the user.

    The problem appears when the ValidateField method is called. Inside it, programmer may show error messages if data is invalid, showing a descriptive message to the user in two ways : with a messagebox or through the QStatusBar ( really, in a QLabel inserted with QStatusBar->addPermanentWidget ( ... ), to show an static red-colored message until input error is solved ).

    If error messages are showed by a MessageBox, the focus returns to the last widget & a blinking cursor is shown. But when the mesage is shown through that StatusBar, the focus returns but no cursor appears !!

    This is confusing to the final user... Any ideas ?

  2. #2
    Join Date
    Jul 2006
    Location
    Catalunya - Spain
    Posts
    117
    Thanks
    16
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Cursor not ivisible

    Nodoby has any clue about this strange behaviour ?

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,013 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Cursor not visible

    Why are you using such a strange way to validate? I suggest you use a QValidator subclass to validate the data and emit a signal from within validate() stating whether input is valid or not. If it's invalid, you can set the focus back to that widget owning the validator and still use the standard tab order feature.

  4. #4
    Join Date
    Jul 2006
    Location
    Catalunya - Spain
    Posts
    117
    Thanks
    16
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Cursor not visible

    Perhaps you misunderstood me or I didn't explain well. I use QValidator, I'va made some format-specific validators, ... to test input syntactic correctness, but when the user presses return / tab, the final value must be tested against a database, or some type of calculation must be done, or...

    As I said, in my first post, I'm working in a core that hides GUI to the programmer, so in the other side the "Business Logic" only receives a "ValidateThisField" method call. If it answers OK, I make the step, if not I remain inside the field.

    QValidators call a fixup method, but doesn't allow to stop the process if that "final validation" fails. So I decided to catch the focusOut event to put here an extra validation.

    Is that an error ? I think this isn't I do need validate on every FIELD EXIT. And this validation could be time-comsuming ( query launch to database, test, ... ).

    So anyway the problem is not the method to validate. I've been testing and if I show a message directly in a QStatusBar ( showMessage () ) between a focus out and a focusin event to the same widget, the cursor dissapears in that widget

    And that's VERY strange, and my real problem...

    And regarding to standard tab order : I do have to override it because Business Logic could, while working ) activate / deactivate the edition of some fields. And if I use standard tab order, you know what happens with tab order when you disable / enable widgets ? It's lost...

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,013 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Cursor not visible

    Quote Originally Posted by jpujolf View Post
    Perhaps you misunderstood me or I didn't explain well. I use QValidator, I'va made some format-specific validators, ... to test input syntactic correctness, but when the user presses return / tab, the final value must be tested against a database, or some type of calculation must be done, or...
    So can't the validator do it?

    As I said, in my first post, I'm working in a core that hides GUI to the programmer, so in the other side the "Business Logic" only receives a "ValidateThisField" method call. If it answers OK, I make the step, if not I remain inside the field.
    I don't really see a problem... Just make the call from the validator instead of the widget.

    QValidators call a fixup method, but doesn't allow to stop the process if that "final validation" fails. So I decided to catch the focusOut event to put here an extra validation.
    Emit a signal from within the validator stating if the input is valid or not. If it's not, place the focus back in the lineedit owning the validator sending the signal.

    Is that an error ? I think this isn't I do need validate on every FIELD EXIT. And this validation could be time-comsuming ( query launch to database, test, ... ).
    It's a "strange approach" and it doesn't work

    So anyway the problem is not the method to validate. I've been testing and if I show a message directly in a QStatusBar ( showMessage () ) between a focus out and a focusin event to the same widget, the cursor dissapears in that widget
    IMO the problem is that the status bar might be stealing the focus, so it's better not to hack the focus but just set it back. And don't do the validation on focus loss - you only need to validate when something actually changes and that's what QValidator is responsible for.

    And regarding to standard tab order : I do have to override it because Business Logic could, while working ) activate / deactivate the edition of some fields. And if I use standard tab order, you know what happens with tab order when you disable / enable widgets ? It's lost...
    You can make a line edit read only instead of disabling it, AFAIR. And you can always set the tab order again, so losing the order is not that much of a problem.

  6. The following user says thank you to wysota for this useful post:

    jpujolf (11th May 2007)

  7. #6
    Join Date
    Jul 2006
    Location
    Catalunya - Spain
    Posts
    117
    Thanks
    16
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Cursor not visible

    Quote Originally Posted by wysota View Post
    So can't the validator do it?

    I don't really see a problem... Just make the call from the validator instead of the widget.
    Validator Can, but musn't, because validation may be VERY time consuming !!! i.e ( I'm in Spain, so dates will be like DD/MM/YY or DD/MM/YYYY. See this code, is my "smart date validator" ( limits years to 19xx, 2xxxx, accepts two formats DD/MM/YY or DD/MM/YYYY and accepts "smart input" )

    Qt Code:
    1. MDateValidator::MDateValidator ( QObject * parent ) : QRegExpValidator ( QRegExp ( "[0-9]{1,2}[/\\.]{0,1}[0-9]{1,2}[/\\.]{0,1}[0-9]{2,4}" ), parent ) {}
    2.  
    3. QValidator::State MDateValidator::validate ( QString & input, int & pos ) const
    4. {
    5. // Empty date => We accept it
    6. if ( input.length() == 0 ) return Acceptable;
    7.  
    8. // Must follw minimal specifications...
    9. if ( QRegExpValidator::validate ( input, pos ) == Invalid )
    10. return Invalid;
    11.  
    12. // 0 : We allow ".", but change it by "/"
    13. input.replace ( '.', "/" );
    14.  
    15. // PreparacionInput prepare
    16. // 1 : day must be 1..31. If first digit is between 4..9 => we change it to 04/09
    17. if ( input.left ( 1 ) > "3" )
    18. {
    19. input = "0" + input;
    20. pos++;
    21. }
    22.  
    23. // If they introduce one-digit day and a bar we add the leading "0"
    24. if ( ( input.length() == 2 ) && ( input.mid ( 1, 1 ) == "/" ) )
    25. {
    26. input.insert ( 0, "0" );
    27. pos++;
    28. }
    29.  
    30. // We do know the day, so we can make a first validation
    31. int Dia = input.mid ( 0, 2 ).toInt();
    32. if ( Dia > 31 ) return Invalid;
    33. if ( ( Dia == 0 ) && ( input.length() < 2 ) ) return Intermediate;
    34.  
    35. // Append bar if they press the first month's day without pushing bar...
    36. if ( ( input.length() > 2 ) && ( input.mid ( 2, 1 ) != "/" ) )
    37. {
    38. input.insert ( 2, "/" );
    39. pos++;
    40. }
    41.  
    42. // If there is no month, they are OK, by now...
    43. if ( input.length() < 4 ) return Intermediate;
    44.  
    45. // If they enter a month before October without the leading zero, we put it
    46. if ( ( input.length() == 5 ) && ( input.mid ( 4, 1 ) == "/" ) )
    47. {
    48. input.insert ( 3, "0" );
    49. pos++;
    50. }
    51.  
    52. // 2 : Month between 1 and 12, but considering the day...
    53. int Mes = input.mid ( 3, 2 ).toInt();
    54. if ( Mes > 12 ) return Invalid;
    55. switch ( Mes )
    56. {
    57. // 30 day months
    58. case 4 : // April
    59. case 5 : // June
    60. case 9 : // September
    61. case 11 : // November
    62. if ( Dia > 30 ) return Invalid;
    63. break;
    64. // Special case : February, we don't know the year, so 29 is possible...
    65. case 2 :
    66. if ( Dia > 29 ) return Invalid;
    67. break;
    68. default :
    69. break;
    70. }
    71.  
    72. // 3 : a month beginning by 2..9, We have to insert a leading 0
    73. if ( input.mid ( 3, 1 ).toInt() > 1 )
    74. {
    75. input.insert ( 3, "0" );
    76. pos++;
    77. }
    78.  
    79. // We append month / year separation, if the put first year's digit without the bar
    80. if ( ( input.length() > 5 ) && ( input.mid ( 5, 1 ) != "/" ) )
    81. {
    82. input.insert ( 5, "/" );
    83. pos++;
    84. }
    85.  
    86. // 4 : Year could begin by 1 ( 19xx ) or 2 ( 2xxx )
    87. if ( input.mid ( 6, 1 ).toInt() > 2 )
    88. {
    89. input.insert ( 6, "20" );
    90. pos += 2;
    91. }
    92.  
    93. // Two / four last digits are for the year...
    94. int Anyo = input.mid ( 6, 4 ).toInt();
    95. if ( Anyo < 1900 ) return Intermediate;
    96.  
    97. if ( MDate::IsValid ( Anyo, Mes, Dia ) )
    98. {
    99. // Here must be your suggested call / signal
    100. return Acceptable;
    101. }
    102. else
    103. return Invalid;
    104. }
    To copy to clipboard, switch view to plain text mode 

    While user enters the date, this validate method tests & corrects user input. But when he presses ENTER or TAB key, even if the date is a valid one, Business Logic may decide it's not a valid date ( i.e a day before today for a payment )

    And here becomes the problem. I cannot assume a call to Business Logic EVERY time a date is Acceptable, because that call could be very time-expensive.

    It's a "strange approach" and it doesn't work
    OK, I accept perhaps is an "strange approach", but is working. And it's quick and efficient. Sometimes we must break "programming-guidelines" to obtain a better performance...

    And I repeat that the problem is not in the validation style but in the fact that everything is working OK, but the cursor dissapears when between the focusout and the focusin I show a message on an external StatusBar. But when i show a modal message, all is running OK

    Emit a signal from within the validator stating if the input is valid or not. If it's not, place the focus back in the lineedit owning the validator sending the signal.

    ...

    IMO the problem is that the status bar might be stealing the focus, so it's better not to hack the focus but just set it back. And don't do the validation on focus loss - you only need to validate when something actually changes and that's what QValidator is responsible for.
    But you will agree with me that I will have the same problem. When I emit the signal, I receive a "invalid" response and move the focus, "I'm fuc***"

    I agree with you that StatusBar is stealing the focus, But I don't understand why...

    I'm calling a method like this in the focusout event ( pseudo-code )

    Qt Code:
    1. void MQEntryFormPrivate::FieldExit ( QWidget * Sender )
    2. {
    3. QWidget * pNext = Sender;
    4.  
    5. // If is valid, we step to the next widget, else we remain
    6. if ( BusinessObject()->ValidateField ( Sender ) )
    7. pNext = this->GetNextFocus ( Sender );
    8.  
    9. // Some irrelevant stuff here...
    10.  
    11. pNext->setFocus();
    To copy to clipboard, switch view to plain text mode 

    Inside business object's ValidateField code, user can show messages, activate & deactivate fields, launch queries, ....

    You can make a line edit read only instead of disabling it, AFAIR. And you can always set the tab order again, so losing the order is not that much of a problem.
    Yes, a QlineEdit. But not a QComboBox, or QRadioButton... And I do need to control that kind of widgets too

  8. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,013 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Cursor not visible

    Quote Originally Posted by jpujolf View Post
    While user enters the date, this validate method tests & corrects user input. But when he presses ENTER or TAB key, even if the date is a valid one, Business Logic may decide it's not a valid date ( i.e a day before today for a payment )
    Not really. You can fetch the "possible valid" state from the logic and cache it somehow and use an intermediate state when you suspect the input to be incomplete.

    And here becomes the problem. I cannot assume a call to Business Logic EVERY time a date is Acceptable, because that call could be very time-expensive.
    I think I just answered that as well


    OK, I accept perhaps is an "strange approach", but is working. And it's quick and efficient. Sometimes we must break "programming-guidelines" to obtain a better performance...
    What happens if you just keep pressing tab (possibly inside an invalid field)?

    And I repeat that the problem is not in the validation style but in the fact that everything is working OK, but the cursor dissapears when between the focusout and the focusin I show a message on an external StatusBar. But when i show a modal message, all is running OK
    As I said in the previous post, you're manipulating with the focus too much. Remember that focusOut causes a focusIn elsewhere and then you force the focus back which again causes a focusOut and focusIn. What does your focusOutEvent look like anyway?


    But you will agree with me that I will have the same problem. When I emit the signal, I receive a "invalid" response and move the focus, "I'm fuc***"
    Sure, but this is easily overcomable. Check if calling selectAll() on the line edit helps.

    I agree with you that StatusBar is stealing the focus, But I don't understand why...

    I'm calling a method like this in the focusout event ( pseudo-code )
    I think you should just reject the focus out event.

    Yes, a QlineEdit. But not a QComboBox, or QRadioButton... And I do need to control that kind of widgets too
    Maybe you should just use a QDataWidgetMapper? Most of the things you require are already there, I think... Anyway, you can repair the tab order with a simple function, as I mentioned before.

  9. #8
    Join Date
    Jul 2006
    Location
    Catalunya - Spain
    Posts
    117
    Thanks
    16
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Cursor not visible

    Quote Originally Posted by wysota View Post
    As I said in the previous post, you're manipulating with the focus too much. Remember that focusOut causes a focusIn elsewhere and then you force the focus back which again causes a focusOut and focusIn. What does your focusOutEvent look like anyway?
    Just calls my form's FieldExit method...

    Sure, but this is easily overcomable. Check if calling selectAll() on the line edit helps.
    I'm doing it... And it doesn't helps me...

    I think you should just reject the focus out event.
    You mean calling QEvent::ignore () ? Is the only test I've not done...

    Maybe you should just use a QDataWidgetMapper? Most of the things you require are already there, I think...
    QDataWidgetMapper could be a solution if I was using it against a model. Is not the case...

    Anyway, thanks for wasting your time answering me. You helped me a lot !!

  10. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,013 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Cursor not visible

    Quote Originally Posted by jpujolf View Post
    Just calls my form's FieldExit method...
    I don't think that's enough.

    I'm doing it... And it doesn't helps me...
    Then probably the widget doesn't have focus after all...


    You mean calling QEvent::ignore () ? Is the only test I've not done...
    Yes.

    QDataWidgetMapper could be a solution if I was using it against a model. Is not the case...
    So it's only a matter of implementing a model It has all you need including the validation inside QAbstractItemModel::setData()
    Anyway, thanks for wasting your time answering me. You helped me a lot !!
    If I felt like wasting my time, I wouldn't be here.

  11. The following user says thank you to wysota for this useful post:

    jpujolf (14th May 2007)

Similar Threads

  1. Make the cursor visible in textEdit (Qt3.3.5)
    By vermarajeev in forum Qt Programming
    Replies: 9
    Last Post: 24th January 2007, 23:50
  2. VS Integration plugins not visible
    By kemp in forum Qt Tools
    Replies: 1
    Last Post: 11th August 2006, 23:22
  3. visible text of textedit
    By regix in forum Qt Programming
    Replies: 3
    Last Post: 26th June 2006, 10:02
  4. hidden QListView column suddenly visible
    By edb in forum Qt Programming
    Replies: 10
    Last Post: 27th January 2006, 09:00
  5. How do I find out which widgets/canvas items are visible?
    By Tommytrojan in forum Qt Programming
    Replies: 11
    Last Post: 6th January 2006, 14:22

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.