Difference between revisions of "WxQt"

From WxWiki
Jump to navigation Jump to search
(→‎Internals: more warning and advices)
(Fixed download instructions as wxQT branch was merged)
(28 intermediate revisions by the same user not shown)
Line 9: Line 9:
 
=== Building the Library ===
 
=== Building the Library ===
  
Go to your development directory and download the source code [https://github.com/reingart/wxWidgets/archive/SOC2014_QT.zip zip archive] or checkout the current wxQT repository ([https://github.com/reingart/wxWidgets "Google Summer of Code 2014" Qt branch]) with:
+
'''Note''': "Google Summer of Code 2014" and previous wxQt branch was merged to master trunk!
 +
 
 +
Go to your development directory and download the source code [https://github.com/reingart/wxWidgets/archive/master.zip zip archive] or checkout the ([https://github.com/wxWidgets/wxWidgets current repository]) with:
  
 
<source>
 
<source>
git clone https://github.com/reingart/wxWidgets.git -b SOC2014_QT
+
git clone https://github.com/wxWidgets/wxWidgets.git
 
cd wxWidgets
 
cd wxWidgets
 
</source>
 
</source>
Line 37: Line 39:
 
You can also try the tests and demos sub-directories.
 
You can also try the tests and demos sub-directories.
  
== Architecture ==
+
== Port status ==
  
=== Internals ===
+
=== Unit Tests results ===
  
wxQT uses the same techniques like in other ports to wrap the Qt toolkit classes inside the wxWidget hierachy.
+
{| style="border: 1px solid #CCCCCC; background:#F9F9F9; border-collapse:collapse; text-align:center;" cellspacing="0" cellpadding="2px" border = "1" align="center"
 +
|-
 +
!Pass
 +
!Fail
 +
!Error
 +
!Total
 +
|-
 +
|style="color:green"|378
 +
|style="color:red"|155
 +
|style="color:red"|18
 +
|551
 +
|-
 +
|style="color:green"|68%
 +
|style="color:red"|28%
 +
|style="color:red"|4%
 +
|100%
 +
|-
 +
|colspan="4" | Status: <font color="orange">'''experimental'''</font>
 +
|-
 +
|}
  
An internal pointer m_qtWindow in wxWindow holds the reference to the QWidget (or derived) counterpart, and is accesible through the virtual method `GetHandle`.
+
=== Completion ===
This pointer and other window styles are set up in the `PostCreation` method that must be called by the derived classes (mostly controls) to initialize the widget correctly.
 
Not doing so will cause painting and deletion issues, as the base class  will not know how to handle the Qt widget.
 
wxControl even provides a protected method QtCreateControl that will do the common initialization (including post creation step).
 
  
'''Warning:''' Take care of not calling any function that can raise an assertion before `PostCreation`, for example wxFAIL_MSG, as it will interrupt the normal initialization, hence the later cleanup will crash.
+
A table attempting to summarize progress in the port can be found at [[WxQt/Status]].
For example, this issue was caused by WXValidateStyle in wxCheckBox::Create, that was failing silently in unit tests, and then raising segmentation faults when the object was later deleted (as Qt checkbox counterpart was never being deleted due the aborted initialization).
 
 
 
Many controls have also other pointers to allow to map different sub-widgets and other features.
 
In the other end, Top Level Windows (frames and dialogs) uses directly the internal window pointer, doing a static cast to return the correct type for `GetHandle`, avoiding multilevel pointer hierarchies.
 
This would be the ideal solution, but not all classes could be mapped 1:1 and that could introduce potential issues (i.e. invalid static casts) and more boilerplate due to additional specific accesor methods.
 
 
 
Note that some special cases are not real windows like the `wxTabFrame` (AUI), so they don't set the internal pointer and hence drawing methods should not be used at all.
 
 
 
Many wxWidgets classes maps 1:1 to Qt ones, but there are some exceptions are (1:N or N:1):
 
 
 
* wxAnyButton (wxButton, wxBitmapButton, wxToggleButton): QPushButton
 
* wxFrame: QMainWindow with a QWidget inside as central widget
 
* wxRadioBox: QGroupBox with a QButtonGroup inside
 
* wxStaticText & wxStaticBitmap: QLabel
 
* wxTextCtrl: QLineEdit or QTextEdit (multiline)
 
* wxWindow (wxPanel): QWidget or QScrollArea
 
 
 
=== Private helpers ===
 
 
 
Qt objects needs to be sub-classed to re-implement the events and connect signals:
 
 
 
* Qt events are just virtual methods that needs to be overridden by the derived classes to handle them
 
* Qt signals can be connected to QObject members or simple functions (thanks to Qt5 new signal slot syntax)
 
 
 
The approach chosen was to use templates to help inherit QObject's (QWidget), providing a common base to handle events and signal infrastructure:
 
 
 
* wxQtSignalHandler< wxWindow >: allows emitting wx events for Qt events & signals. This should be used used for all QObjects derivatives that are not widgets, for example QAction (used for shortcut / accelerators).
 
* wxQtEventSignalHandler< QWidget, wxWindow >: derived from `wxQtSignalHandler`, also handles basic events (change, focus, mouse, keyboard, paint, close, etc.). This should be used for all QWidget derivatives (controls, top level windows, etc.)
 
 
 
Both templates also have some safety checks to avoid invalid spurious access to deleted wx objects (using a special pointer to the wx instance stored in the Qt object, that is reseted to NULL when the wx counterpart is deleted).
 
This is due that in some situations, Qt object could still be referenced in the Qt event queue, so it cannot be removed immediately.
 
 
 
Note that no public wxWidget class should be derived directly from QWidget as they could have different lifespans and other implications to run time type systems (RTTI).
 
Some QObjects are even owned by Qt (for example: menubar, statusbar) and some parents (ie. `QTabWidget`) cannot be deleted immediately in some circumstances (they would cause segmentation faults due spurious events / signals caused by the children destruction if not correctly handled as explained previously)
 
 
 
Although some Qt headers are included in public wx headers, this dependencies should be avoided as this could change in the future (decoupling completely the public wxQT headers from Qt).
 
 
 
=== Adding files ===
 
 
 
To add a Qt derived class simply put it in a .h file and add the corresponding .cpp file to the build/bakefiles/files.bkl e.g.:
 
 
 
<source>
 
<set var="QT_LOWLEVEL_HDR" hints="files">
 
    wx/qt/menuitem.h
 
</set>
 
 
 
<set var="QT_LOWLEVEL_SRC" hints="files">
 
    src/qt/menuitem.cpp
 
</set>
 
</source>
 
 
 
From within of the bakefiles directory, regenerate the autoconf files with:
 
 
 
<source>
 
bakefile_gen --formats autoconf
 
</source>
 
 
 
Generate the 'configure' script in your wxQt root directory with:
 
 
 
<source>
 
autoconf
 
</source>
 
 
 
'''IMPORTANT NOTE''': The precompilation step (Qt's moc) is no more needed so the build rule was removed. There is no need to use  Q_OBJECT nor Q_SLOTS macros.
 
 
 
<source>
 
// include/wx/qt/menuitem.h
 
 
 
class wxMenuItem : public wxMenuItemBase
 
{
 
  // ...
 
};
 
 
 
class wxQtAction : public QAction
 
{
 
public:
 
    wxQtAction( wxMenuItem *menuItem, const QString &text, QObject *parent );
 
  
private:
+
Summary of features running (see bellow caveats and known issues):
    void OnActionTriggered( bool checked );
 
  
private:
+
* Application, event loop (limited), FD/Socket monitoring, etc.
    wxMenuItem *m_menuItem;
+
* Most core controls: wxButton, wxBitmapButton, wxToggleButton, wxChoice, wxComboBox, wxTextCtrl, wxStaticText, wxStaticBox, wxStaticBitmap, wxRadioBox, wxCheckBox, wxGauge, wxSlider, wxSpinCtrl, wxNotebook, etc.
};
+
* Some advanced controls: wxCalendar, wxListCtrl, wxTreeCtrl, wxGrid.
</source>
+
* Top Level Windows: wxFrame (wxMenuBar, wxStatusBar, wxToolBar), wxDialog and common dialogs and wizards
 +
* AUI (limited)
 +
* Cairo graphic renderer (limited, not using cairo qt surface)
 +
* OpenGL (limited, some drawing issues)
  
=== Coding guidelines ===
+
General interface is almost 100% complete, at least for wxPython, as it compiles all classes (701 SIP cpp files, except wxHTML2 that is not implemented). See [https://github.com/reingart/wxWidgets/wiki/wxPythonQtPhoenixNotes Phoenix] notes for more information.
  
* If you leave out an implementation for whatever reason, then mark it with the wxMISSING_IMPLEMENTATION() macro from wx/qt/utils.h i.e.:
+
=== Known Open Issues ===
  
<source>
+
Although simple apps works, there are some problems that will affect more complex applications in the near term:
void wxSomeClass::SomeMethod()
 
{
 
    wxMISSING_IMPLEMENTATION( __FUNCTION__ );
 
}
 
</source>
 
  
or if only some implementation is missing like evaluating flags:
+
* Complex painting is failing "mysteriously" in some situations (see [https://github.com/reingart/wxWidgets/wiki/WxQtClippingProblems clipping problems] notes). Also, still there are many Qt warning about QPainter used incorrectly (most of them should not happen, there could be wrong logic about scroll areas or center widget where Qt painting is not direct / orthogonal to wx use cases). wxRichTextCtrl is the leading case here.
 
+
* Mouse capture seems not to be working correctly, and that may be causing some issues in controls like wxHTMLWindow, wxHyperlinkCtrl, AUI, etc. There seems that some semantics are very different between wxWidgets and Qt about mouse movements events (see mouseTracking QWidget attribute). It is somewhat strange as some other samples relating mouse work (for example, MDI tiny doodling).
<source>
+
* Nested Event Loop implementation is not optimal, as it is doing some kind of busy waiting. It could be enhanced with QEventLoop but didn't work, in fact it get worse: for example, the app no longer exits and some dialogs get blocked, test_gui never ends anymore, etc. Maybe the event loop could be refactorized with QAbstractEventDispatcher to join more tightly both wx and Qt event queues (the docs says there is an example for motif). NOTE that this doesn't affect main application event loop nor modal dialogs, only wxExecute.
void wxSomeClass::SomeMethod( unsigned methodFlags )
 
{
 
    wxMISSING_IMPLEMENTATION( "methodFlags" );
 
}
 
</source>
 
 
 
* To avoid name clashes with a 3rd party library like boost, and due precompilation step was removed, don't use the internal moc keywords 'signals' and 'slots':
 
 
 
<source>
 
class wxQtClass : public QClass
 
{
 
private:
 
    void OnSignal();
 
};
 
</source>
 
 
 
=== Naming conventions ===
 
 
 
* Global helper classes and global functions should be prefixed with 'wxQt' i.e.:
 
 
 
<source>
 
class wxQtButton : public QPushButton
 
{
 
}
 
 
 
QRect wxQtConvertRect( const wxRect & );
 
</source>
 
 
 
* Internal methods in publicly visible classes (like wxWindow) should be prefixed with 'Qt' i.e.:
 
 
 
<source>
 
class wxWindow : public wxWindowBase
 
{
 
public:
 
    QWidget *QtGetContainer() const;
 
};
 
</source>
 
 
 
== Port status ==
 
 
 
A table attempting to summarize progress in the port can be found at [[WxQt/Status]].
 
  
 +
Also, there are still some important features like  webview (webkit), printing, drag and drop, data view control, native renderer, etc. that aren't implementated. Many of them should be easily achievable (at least webkit, following wxGTK work).
  
I (Peter Most) can be contacted on the developer mailing list.
+
=== Developers ===
 +
Developers can be contacted on the developer mailing list (not everyone could be active by now):
 +
* Mariano Reingart (GSoC 2014 developer)
 +
* Sean D'Epagnier (2014 contributor)
 +
* Javier Torres (GSoC 2010 developer)
 +
* Kolya Kosenko (2010, calendar and other contributions)
 +
* Peter Most (original developer)

Revision as of 11:38, 11 September 2014

Getting started

Prerequisites

Currently, wxQT needs Qt 5 or later (recommended version is Qt 5.2.1). Other dependencies are needed depending on the features to be used (fo example cairo, opengl, jpg/tiff, etc.). For more information see docs/qt folder shipped with the source code, and/or Ubuntu / Android notes.

Building the Library

Note: "Google Summer of Code 2014" and previous wxQt branch was merged to master trunk!

Go to your development directory and download the source code zip archive or checkout the (current repository) with:

git clone https://github.com/wxWidgets/wxWidgets.git
cd wxWidgets

Now create the build directory e.g.: 'bldqt5' and from it call the configure script (using Qt option) and run make to start the compilation process:

mkdir bldqt5
cd bldqt5
../configure --with-qt --enable-debug
make

Building Samples, Tests and Demos

After successful build, you can go to the samples sub-directory, compile and run them, for example:

cd samples/controls
make
./controls

You can also try the tests and demos sub-directories.

Port status

Unit Tests results

Pass Fail Error Total
378 155 18 551
68% 28% 4% 100%
Status: experimental

Completion

A table attempting to summarize progress in the port can be found at WxQt/Status.

Summary of features running (see bellow caveats and known issues):

  • Application, event loop (limited), FD/Socket monitoring, etc.
  • Most core controls: wxButton, wxBitmapButton, wxToggleButton, wxChoice, wxComboBox, wxTextCtrl, wxStaticText, wxStaticBox, wxStaticBitmap, wxRadioBox, wxCheckBox, wxGauge, wxSlider, wxSpinCtrl, wxNotebook, etc.
  • Some advanced controls: wxCalendar, wxListCtrl, wxTreeCtrl, wxGrid.
  • Top Level Windows: wxFrame (wxMenuBar, wxStatusBar, wxToolBar), wxDialog and common dialogs and wizards
  • AUI (limited)
  • Cairo graphic renderer (limited, not using cairo qt surface)
  • OpenGL (limited, some drawing issues)

General interface is almost 100% complete, at least for wxPython, as it compiles all classes (701 SIP cpp files, except wxHTML2 that is not implemented). See Phoenix notes for more information.

Known Open Issues

Although simple apps works, there are some problems that will affect more complex applications in the near term:

  • Complex painting is failing "mysteriously" in some situations (see clipping problems notes). Also, still there are many Qt warning about QPainter used incorrectly (most of them should not happen, there could be wrong logic about scroll areas or center widget where Qt painting is not direct / orthogonal to wx use cases). wxRichTextCtrl is the leading case here.
  • Mouse capture seems not to be working correctly, and that may be causing some issues in controls like wxHTMLWindow, wxHyperlinkCtrl, AUI, etc. There seems that some semantics are very different between wxWidgets and Qt about mouse movements events (see mouseTracking QWidget attribute). It is somewhat strange as some other samples relating mouse work (for example, MDI tiny doodling).
  • Nested Event Loop implementation is not optimal, as it is doing some kind of busy waiting. It could be enhanced with QEventLoop but didn't work, in fact it get worse: for example, the app no longer exits and some dialogs get blocked, test_gui never ends anymore, etc. Maybe the event loop could be refactorized with QAbstractEventDispatcher to join more tightly both wx and Qt event queues (the docs says there is an example for motif). NOTE that this doesn't affect main application event loop nor modal dialogs, only wxExecute.

Also, there are still some important features like webview (webkit), printing, drag and drop, data view control, native renderer, etc. that aren't implementated. Many of them should be easily achievable (at least webkit, following wxGTK work).

Developers

Developers can be contacted on the developer mailing list (not everyone could be active by now):

  • Mariano Reingart (GSoC 2014 developer)
  • Sean D'Epagnier (2014 contributor)
  • Javier Torres (GSoC 2010 developer)
  • Kolya Kosenko (2010, calendar and other contributions)
  • Peter Most (original developer)