Page 89 of 106

Re: Welcome to the Project Developers' Table

Posted: Wed Nov 03, 2010 11:15 am
by Rathinagiri
Thanks a lot for the answer Francesco.

So, with the updated version of Harbour & HBQT (built with 02-11-2010 nightly source of Harbour 15729), shall I try to reinstate :disconnect()?

Re: Welcome to the Project Developers' Table

Posted: Thu Nov 04, 2010 4:26 am
by Rathinagiri
Even now, with the new version, if we disconnect an unconnected event, it gives out the following error.

Error HBQT/1299 Argument error

Called from __HBQT_ERROR( 0 )
Called from QLINEEDIT:DISCONNECT( 0 )
Called from TEXTBOX:CREATE( 553 )
Called from WINDOW:CREATEPENDINGCHILDCONTROLS( 1336 )
Called from WINDOW:ACTIVATE( 1531 )
Called from MAIN( 175 )

Re: Welcome to the Project Developers' Table

Posted: Thu Nov 04, 2010 5:39 am
by Rathinagiri
2010-11-04 10:55 UTC+0530 Rathinagiri ( srgiri@dataone.in )
* source/browse.prg
* source/checkbox.prg
* source/checkbutton.prg
* source/combobox.prg
* source/control.prg
* source/datepicker.prg
* source/editbox.prg
* source/grid.prg
* source/ipaddress.prg
* source/listbox.prg
* source/menuitem.prg
* source/monthcalendar.prg
* source/printer.prg
* source/radiogroup.prg
* source/slider.prg
* source/spinner.prg
* source/tab.prg
* source/textbox.prg
* source/tree.prg
* source/window.prg
* Code changed to meet current HBQT version. :disconnect() event is now checked for whether the event is already connected.
* samples/textbox/demo_4.prg
! Fixed a small bug.

Re: Welcome to the Project Developers' Table

Posted: Thu Nov 04, 2010 10:48 pm
by mrduck
I've done some more work on ABM2 and I think I've found some points I want to discuss with you.

It seems to me that all HMG windows are implemented with QMainWindow Qt object. I ask you to open at assistant and search for QMainWindow class and scroll down to the nice graph.
QMainWindow has several areas it may divided into. They are not mandatory, you can have or not have them, but if you use them your work is made more easy.
In Qt, for example, toolbars are moveable, you can put them at top, bottom, left and right. If you have a tool bar but don't include the objects in the form in a QWidget and assign it to the central widget position, it happens that the moving toolbar can overwrite the form objects. There may also be problems for input focus... and you need to add the toolbar height to objects row to not overwrite the toolbar at the top, but when moving it to another position that empty space is not nice to see. I experimented all these during ABM2 conversion...
The solution is to add the hmg objects of the form to a QWidget and then set that QWidget as the central widget of QMainWindow. IN this case QT will take care of all movements.
QWidget acts as a container of a group of objects, and this is already used in hmg TAB, to hold all the objects of a tab page.

How can we add a hmg object to a QWidget ?
As first step we need a QWidget object, so I created a hmg Widget class, whose only method is Create() and this is turn creates a QWidget.
Then I tried to use :parent to specify the container but it didn't work because in conflict with TAB.
As first step we need a QWidget object, so I created a hmg Widget class, whose only method is Create() and this is turn creates a QWidget.
Browsing the code I saw that all Create() class use this kind of code:

Code: Select all

IF valtype( ::oContainer ) == 'U'
   ::oQTObject := QLabel( ::oParent:oQTObject )
ELSE
   ::oQTObject := QLabel( ::oContainer:oQTObject )
ENDIF
and decided to set oContainer in my code to specify the container, and it worked.


As you know, Qt objects are created only at window:Activate() and so at the moment we must do all the dirty job in the on init function. In this function we assign the toolbar and the widget at the window and Qt will take care of everything.


Why did I explain all this ? Various reasons

1) do you want me to commit these changes ? at the moment they don't touch any core code, there is just one class and everything must be done in "user-code"
2) I'd like to have some more Qt features integrated in hmg and this can be done only after a discussion on what and how to implement the features, they may have side-effects
3) from my tests, using :parent interferes with TAB, it would be nice to better defines this, or better make :parent generic
4) what about adding layouts to hmg ? Docks ?

Would you like to create different threads for these topics ? Read the message in this more explicit way: are you willing to discuss and - perhaps - change some inner code of hmg ?

Re: Welcome to the Project Developers' Table

Posted: Fri Nov 05, 2010 2:23 am
by Rathinagiri
IMHO, the main objects of HMG4 are, simplicity and backward compatibility. If these are not affected, yes we can change the inner code.

I want to know what are the changes in 'user-code'.

Please commit the changes and let us know about the difference...

Re: Welcome to the Project Developers' Table

Posted: Fri Nov 05, 2010 10:51 pm
by mrduck
rathinagiri wrote:Please commit the changes and let us know about the difference...
Hi Rathinagiri, I just committed the code.

Code: Select all

2010-11-05 10:55 UTC-0300 Francesco Perillo (<fperillo@gmail.com>)
  * source/widget.prg
    * Implemented WIDGET class, the equivalent of QWidget.

  * samples/widget/demo_3a.prg
    * sample to show what happens when relocating toolbar without using WIDGET
  * samples/widget/demo_3b.prg
    * sample to show what happens when relocating toolbar using WIDGET and
	  how to assign the central widget at runtime
I was able to do the hmg way, using only basic classes and no strange runtime things.

I did not implemented WIDGET class in hmg.ch... I never did that kind of job and I may create errors, so I ask you to take care of it.

In two words: define a Widget and assign all the objects to it:

Code: Select all

 myWidget1 := Widget():New()

 With Object l1 := Label():New()
   :Name   := "l1"
   :parent := myWidget1
   :Value  := "this is myWidget1"
and then assign this widget to the central widget area of qmainwindow:

Code: Select all

myWidget1:CentralWidgetOf := oWindow
Run widget/demo_3a and 3b samples, move the toolbar around and see the difference.


Actually, in TABPAGE a QWidget is defined (as it should be) to be the container of all the objects in that page. I think that the QWidget usage should be changed to hmg widget. I say this because Widget should be the basic building block of every form, and on top of widget it is possible to create different interesting layouts !

Re: Welcome to the Project Developers' Table

Posted: Fri Nov 05, 2010 10:57 pm
by mrduck
In hmg.ch there are some places where length is mispelled:
- [ MAXLENGTH <nMaxLenght> ]
+ [ MAXLENGTH <nMaxLength> ]

- [:MaxLenght := <nMaxLenght> ]
+ [:MaxLength := <nMaxLength> ]

and of course also the class methods names should be changed...

Re: Welcome to the Project Developers' Table

Posted: Fri Nov 05, 2010 11:06 pm
by mrduck
Sorry Rathinagiri,
browsing the code today I found this change in control:OnLostFocus:

Code: Select all

         IF .NOT. ::oQTObject:connect( QEvent_FocusOut , ::bOnLostFocus )
            ::oQTObject:disconnect( QEvent_FocusOut )
            IF .NOT. ::oQTObject:connect( QEvent_FocusOut , ::bOnLostFocus )
               // Can't connect the event... error
            ENDIF
         ENDIF
Disconnecting a non existant event gives a RTE ? It shouldn't! If it does please check with a more recent version of hbqt.

Perhaps we should think about adding [dis]connect methods to class CONTROL

In the next method, OnClick:

Code: Select all

         ::bOnClick := bValue
         ::oQTObject:DisConnect( "clicked()" )
         ::oQTObject:Connect( "clicked()" , ::bOnClick )
so it seems that it's ok to disconnect a not-connected signal...

Re: Welcome to the Project Developers' Table

Posted: Fri Nov 05, 2010 11:22 pm
by mrduck
Last message for today, I promise :-)

see this code:

Code: Select all

METHOD OnClick( bValue ) CLASS CONTROL

   IF ::lCreated
      IF Pcount() == 0
         RETURN ::bOnClick
      ELSEIF Pcount() == 1
         ::bOnClick := bValue
         *::oQTObject:DisConnect( "clicked()" )
         ::oQTObject:Connect( "clicked()" , ::bOnClick )
      ENDIF
   ELSE
      IF pcount() == 0
         RETURN ::bOnClick
      ELSEIF pcount() == 1
         ::bOnClick := bValue
      ENDIF
   ENDIF

   RETURN NIL
I propose some changes (code not tested, it's just a proposal)

Code: Select all

METHOD OnClick( bValue ) CLASS CONTROL

      // one code for  both ::lCreated values
      IF Pcount() > 1
         // error
         ::bOnClick := NIL
      ELSEIF Pcount() == 1
         IF HB_isBlock( bValue )  // check parameter type to avoid chaos
             ::bOnClick := bValue
         ELSE
             // Generate error and/or
             ::bOnClick := NIL   // must remove old codeblock
             return NIL
          ENDIF

         IF ::lCreated .and. hb_isblock( ::bOnClick )
            // force disconnect, ignore return value
            ::oQTObject:DisConnect( "clicked()" )
            // connect
            if ! ::oQTObject:Connect( "clicked()" , ::bOnClick ) 
                // generate error (some errors already generated by :connect,
                // if it returns .F. after a :disconnect there may be other problems...
                ::bOnClick := NIL
         ENDIF  //::lCreated
      ENDIF
 
   RETURN ::bOnClick
A bit of code refactoring, a bit of parameter checking, a bit of error reporting.... just an idea....

Re: Welcome to the Project Developers' Table

Posted: Mon Nov 08, 2010 3:28 am
by Rathinagiri
After a festival holiday and a small tour, I had just now returned and seen your posts. I try to understand what happens with Widget class. :)
Disconnecting a non existant event gives a RTE ? It shouldn't! If it does please check with a more recent version of hbqt.
Yes. Disconnecting a non existent event gives a RTE. Can you tell me which version you are using? I am using Release 15729.

Unconnected signals are not giving RTE.
Perhaps we should think about adding [dis]connect methods to class CONTROL
Yes, that is a nice idea. However, some signals/events are widget specific and on change of one widget is different from on change of another widget.