diff --git a/LICENSE.GPL b/LICENSE.GPL
new file mode 100644
--- /dev/null
+++ b/LICENSE.GPL
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/LICENSE.LGPL b/LICENSE.LGPL
new file mode 100644
--- /dev/null
+++ b/LICENSE.LGPL
@@ -0,0 +1,165 @@
+                   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,116 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# OPTIONS_GHC -W -fwarn-incomplete-patterns -fwarn-unused-do-bind #-}
+
+import Control.Monad (when)
+import Distribution.PackageDescription (PackageDescription)
+import Distribution.Simple (defaultMainWithHooks, simpleUserHooks)
+import Distribution.Simple.LocalBuildInfo (
+  LocalBuildInfo,
+  absoluteInstallDirs,
+  bindir,
+  withPrograms,
+  )
+import Distribution.Simple.Program (
+  Program,
+  ProgramSearchPathEntry (ProgramSearchPathDir),
+  programFindLocation,
+  runDbProgram,
+  simpleProgram,
+  )
+import Distribution.Simple.Program.Find (findProgramOnSearchPath)
+import Distribution.Simple.Setup (
+  CleanFlags,
+  CopyDest (NoCopyDest),
+  cleanVerbosity,
+  fromFlagOrDefault,
+  )
+import Distribution.Simple.UserHooks (
+  UserHooks (
+    hookedPrograms,
+    cleanHook,
+    copyHook,
+    instHook,
+    postConf
+    ),
+  )
+import Distribution.Simple.Utils (info, installExecutableFile)
+import Distribution.Verbosity (normal, verbose)
+import System.Directory (
+  createDirectoryIfMissing,
+  doesFileExist,
+  getCurrentDirectory,
+  removeFile,
+  )
+import System.FilePath ((</>), joinPath)
+
+main :: IO ()
+main = defaultMainWithHooks qtahHooks
+
+qtahHooks :: UserHooks
+qtahHooks = simpleUserHooks
+  { hookedPrograms = [listenerGenProgram, qmakeProgram]
+  , postConf = \_ _ _ lbi -> generateSources lbi
+  , copyHook = \pd lbi uh cf -> do doInstall pd lbi
+                                   copyHook simpleUserHooks pd lbi uh cf
+  , instHook = \pd lbi uh if' -> do doInstall pd lbi
+                                    instHook simpleUserHooks pd lbi uh if'
+  , cleanHook = \pd z uh cf -> do doClean cf
+                                  cleanHook simpleUserHooks pd z uh cf
+  }
+
+listenerGenProgram :: Program
+listenerGenProgram =
+  (simpleProgram "qtah-listener-gen")
+  { programFindLocation = \verbosity _ ->
+    findProgramOnSearchPath verbosity [ProgramSearchPathDir "."] "qtah-listener-gen"
+  }
+
+qmakeProgram :: Program
+qmakeProgram = simpleProgram "qmake"
+
+generateSources :: LocalBuildInfo -> IO ()
+generateSources localBuildInfo = do
+  -- Generate binding sources for the generated C++ listener classes.
+  let programDb = withPrograms localBuildInfo
+  runDbProgram normal listenerGenProgram programDb ["--gen-hs-dir", "."]
+
+doInstall :: PackageDescription -> LocalBuildInfo -> IO ()
+doInstall packageDesc localBuildInfo = do
+  startDir <- getCurrentDirectory
+  let binDir = bindir $ absoluteInstallDirs packageDesc localBuildInfo NoCopyDest
+  createDirectoryIfMissing True binDir
+  installExecutableFile verbose
+                        (startDir </> "qtah-listener-gen")
+                        (binDir </> "qtah-listener-gen")
+
+doClean :: CleanFlags -> IO ()
+doClean cleanFlags = do
+  startDir <- getCurrentDirectory
+  let interfaceDir = startDir </>
+                     joinPath ["src", "Graphics", "UI", "Qtah", "Generator", "Interface"]
+  delFile $ interfaceDir </> "Listener.hs"
+  delFile $ interfaceDir </> "Listener.hs-boot"
+
+  where verbosity = fromFlagOrDefault normal $ cleanVerbosity cleanFlags
+
+        delFile path = do
+          exists <- doesFileExist path
+          when exists $ do
+            info verbosity $ concat ["Removing file ", path, "."]
+            removeFile path
diff --git a/qtah-generator.cabal b/qtah-generator.cabal
new file mode 100644
--- /dev/null
+++ b/qtah-generator.cabal
@@ -0,0 +1,149 @@
+name: qtah-generator
+version: 0.1.0
+synopsis: Generator for Qtah Qt bindings
+homepage: http://khumba.net/projects/qtah
+license: LGPL-3
+license-files: LICENSE.GPL, LICENSE.LGPL
+author: Bryan Gardiner <bog@khumba.net>
+maintainer: Bryan Gardiner <bog@khumba.net>
+copyright: Copyright 2015-2016 Bryan Gardiner
+category: Graphics
+build-type: Custom
+cabal-version: >=1.10
+description:
+  Qtah is a set of Qt bindings for Haskell.  This package is a Hoppy FFI
+  generator.  You shouldn't need it directly; rather, qtah-cpp and qtah use it
+  as part of their build processes.
+
+extra-source-files:
+    qtah-listener-gen
+
+-- This library is necessary so that qtah-cpp and qtah can build-depends on
+-- qtah-generator.  build-depends requires a library in the target package.
+-- build-tools can't be used because these don't get installed automatically[1]
+-- and Cabal also complained about not being able to find the versions of the
+-- qtah-generator binary, when I tried to specify version dependencies.
+--
+-- This library has an empty module so that "cabal haddock" doesn't fail.
+--
+-- [1] https://github.com/haskell/cabal/issues/220
+library
+  default-language: Haskell2010
+  hs-source-dirs: src
+  build-depends:
+      base >=4 && <5
+  other-modules:
+      Graphics.UI.Qtah.Generator.Empty
+
+executable qtah-generator
+  build-depends:
+      base >=4 && <5
+    , containers >=0.5 && <0.6
+    , directory >=1.2 && <1.3
+    , filepath >=1.3 && <1.5
+    , hoppy-generator >=0.2 && <0.3
+    , hoppy-std >=0.2 && <0.3
+    , haskell-src >=1.0 && <1.1
+    , mtl >=2.1 && <2.3
+    , process >=1.2 && <1.5
+  hs-source-dirs: src
+  main-is: Main.hs
+  other-modules:
+      Graphics.UI.Qtah.Generator.Common
+    , Graphics.UI.Qtah.Generator.Flag
+    , Graphics.UI.Qtah.Generator.Flags
+    , Graphics.UI.Qtah.Generator.Interface.Callback
+    , Graphics.UI.Qtah.Generator.Interface.Core
+    , Graphics.UI.Qtah.Generator.Interface.Core.QChar
+    , Graphics.UI.Qtah.Generator.Interface.Core.QChildEvent
+    , Graphics.UI.Qtah.Generator.Interface.Core.QCoreApplication
+    , Graphics.UI.Qtah.Generator.Interface.Core.QDir
+    , Graphics.UI.Qtah.Generator.Interface.Core.QEvent
+    , Graphics.UI.Qtah.Generator.Interface.Core.QList
+    , Graphics.UI.Qtah.Generator.Interface.Core.QMargins
+    , Graphics.UI.Qtah.Generator.Interface.Core.QMarginsF
+    , Graphics.UI.Qtah.Generator.Interface.Core.QObject
+    , Graphics.UI.Qtah.Generator.Interface.Core.QPoint
+    , Graphics.UI.Qtah.Generator.Interface.Core.QPointF
+    , Graphics.UI.Qtah.Generator.Interface.Core.QRect
+    , Graphics.UI.Qtah.Generator.Interface.Core.QRectF
+    , Graphics.UI.Qtah.Generator.Interface.Core.QSize
+    , Graphics.UI.Qtah.Generator.Interface.Core.QSizeF
+    , Graphics.UI.Qtah.Generator.Interface.Core.QString
+    , Graphics.UI.Qtah.Generator.Interface.Core.QStringList
+    , Graphics.UI.Qtah.Generator.Interface.Core.QTimerEvent
+    , Graphics.UI.Qtah.Generator.Interface.Core.QVector
+    , Graphics.UI.Qtah.Generator.Interface.Core.Types
+    , Graphics.UI.Qtah.Generator.Interface.EventListener
+    , Graphics.UI.Qtah.Generator.Interface.Gui
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QActionEvent
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QClipboard
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QCloseEvent
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QColor
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QDoubleValidator
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QEnterEvent
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QExposeEvent
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QFocusEvent
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QHideEvent
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QHoverEvent
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QInputEvent
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QIntValidator
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QKeyEvent
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QMouseEvent
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QPolygon
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QPolygonF
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QRegion
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QShowEvent
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QValidator
+    , Graphics.UI.Qtah.Generator.Interface.Gui.QWheelEvent
+    , Graphics.UI.Qtah.Generator.Interface.Imports
+    , Graphics.UI.Qtah.Generator.Interface.Listener
+    , Graphics.UI.Qtah.Generator.Interface.Widgets
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractScrollArea
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSlider
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSpinBox
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QAction
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QActionGroup
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QApplication
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QBoxLayout
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QButtonGroup
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QCheckBox
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QDial
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QDialog
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QDialogButtonBox
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QDoubleSpinBox
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QFileDialog
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QFormLayout
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QFrame
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QGridLayout
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QGroupBox
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QHBoxLayout
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QLabel
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QLayout
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QLayoutItem
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QLineEdit
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QMainWindow
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QMenu
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QMenuBar
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QMessageBox
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QProgressBar
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QPushButton
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QRadioButton
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QRubberBand
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QScrollArea
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QScrollBar
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QSlider
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QSpinBox
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QSplitter
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QStackedLayout
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QStackedWidget
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QStatusBar
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QTabWidget
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QTextEdit
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QVBoxLayout
+    , Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget
+    , Graphics.UI.Qtah.Generator.Module
+    , Graphics.UI.Qtah.Generator.Types
+  ghc-options: -W -fwarn-incomplete-patterns -fwarn-unused-do-bind
+  default-language: Haskell2010
diff --git a/qtah-listener-gen b/qtah-listener-gen
new file mode 100644
--- /dev/null
+++ b/qtah-listener-gen
@@ -0,0 +1,276 @@
+#!/usr/bin/env bash
+
+# This file is part of Qtah.
+#
+# Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+set -euo pipefail
+
+msg() {
+    echo "qtah-listener-gen: $*"
+}
+
+help() {
+    cat <<EOF
+qtah-listener-gen: Generates listener classes for wrapping Qt signals.
+
+Options:
+  --help              : Display this menu.
+  --gen-cpp-dir <dir> : Generates C++ listener classes in listener.cpp and
+                        listener.hpp in the given directory.
+  --gen-hs-dir <dir>  : Generates bindings to be linked into a Hoppy generator
+                        in the Haskell project rooted at the given directory.
+
+At least one of --gen-cpp-dir or --gen-hs-dir is required.
+EOF
+}
+
+cppDir=
+hsDir=
+
+while [[ $# -ne 0 ]]; do
+    case "$1" in
+        --help) help; exit 0;;
+        --gen-cpp-dir) shift; cppDir="${1:?--gen-cpp-dir requires an argument.}";;
+        --gen-hs-dir) shift; hsDir="${1:?--gen-hs-dir requires an argument.}";;
+        *) msg "Unrecognized argument: $1"; exit 1;;
+    esac
+    shift
+done
+
+if [[ -z $cppDir ]] && [[ -z $hsDir ]]; then
+    msg "At least one of --gen-cpp-dir or --gen-hs-dir is required.  See --help."
+    exit 1
+fi
+
+installGen() {
+    local src="${1:?}" dest="${2:?}"
+    if cmp -s "$src" "$dest"; then
+        rm "$src"
+    else
+        mv "$src" "$dest"
+    fi
+}
+
+forEachListener() {
+    local fn="${1:?forEachListener requires the name of a function to call.}"
+
+    # Keep the includes in the C++ section up-to-date with the types used here.
+    $fn Bool "bool"
+    $fn Double "double"
+    $fn Int "int"
+    $fn IntBool "int|bool"
+    $fn IntInt "int|int"
+    $fn PtrQAbstractButton "QAbstractButton*"
+    $fn PtrQAbstractButtonBool "QAbstractButton*|bool"
+    $fn PtrQAction "QAction*"
+    $fn PtrQObject "QObject*"
+    $fn PtrQWidgetPtrQWidget "QWidget*|QWidget*"
+    $fn QAbstractSliderAction "QAbstractSlider::SliderAction"
+    $fn QClipboardMode "QClipboard::Mode"
+    $fn QPoint "QPoint"
+    $fn QSize "QSize"
+    $fn QString "QString"
+    $fn "" ""
+}
+
+#### Generate C++ listener classes.
+
+if [[ -n $cppDir ]]; then
+    msg "Generating C++ listener classes."
+    exec \
+        {fhpp}>"$cppDir/listener.hpp.new" \
+        {fcpp}>"$cppDir/listener.cpp.new"
+    sayHpp() { echo "$*" >&$fhpp; }
+    sayCpp() { echo "$*" >&$fcpp; }
+
+    sayHpp '////////// GENERATED FILE, EDITS WILL BE LOST //////////'
+    sayHpp
+    sayHpp '#ifndef QTAH_LISTENERS_HPP'
+    sayHpp '#define QTAH_LISTENERS_HPP'
+    sayHpp
+    sayHpp '#include <string>'
+    sayHpp '#include <QAbstractButton>'
+    sayHpp '#include <QAbstractSlider>'
+    sayHpp '#include <QAction>'
+    sayHpp '#include <QClipboard>'
+    sayHpp '#include <QObject>'
+    sayHpp '#include <QPoint>'
+    sayHpp '#include <QSize>'
+    sayHpp '#include <QWidget>'
+    sayHpp '#include "b_callback.hpp"'
+
+    sayCpp '////////// GENERATED FILE, EDITS WILL BE LOST //////////'
+    sayCpp
+    sayCpp '#include "listener.hpp"'
+    sayCpp
+    sayCpp '#include <iostream>'
+
+    writeCpp() {
+        local -r name="${1?}" params="${2?}"
+        local -r className="Listener${name}"
+        local -r callbackClassName="Callback${name}Void"
+        local paramList=""
+        local paramTypeList=""
+        local paramNameList=""
+        local n=1
+        if [[ -n $params ]]; then
+            while read type; do
+                [[ -n $paramList ]] && paramList+=', '
+                [[ -n $paramTypeList ]] && paramTypeList+=','
+                [[ -n $paramNameList ]] && paramNameList+=', '
+                paramList+="${type} arg${n}"
+                paramTypeList+="${type}"
+                paramNameList+="arg${n}"
+                ((n++))
+            done < <(tr '|' '\n' <<<"$params")
+        fi
+
+        sayHpp
+        sayHpp "class ${className} : public QObject {"
+        sayHpp "    Q_OBJECT"
+        sayHpp
+        sayHpp "public:"
+        sayHpp "    typedef ${callbackClassName} callback;"
+        sayHpp "    ${className}(callback f, QObject* parent = 0);"
+        sayHpp "    bool connectListener(QObject* source, const std::string& signal);"
+        sayHpp
+        sayHpp "public slots:"
+        sayHpp "    void invoke(${paramList});"
+        sayHpp
+        sayHpp "private:"
+        sayHpp "    callback f_;"
+        sayHpp "    bool connected_;"
+        sayHpp "};"
+
+        sayCpp
+        sayCpp "${className}::${className}(${className}::callback f, QObject* parent) :"
+        sayCpp "    QObject(parent), f_(f), connected_(false) {}"
+        sayCpp
+        sayCpp "bool ${className}::connectListener(QObject* source, const std::string& signal) {"
+        sayCpp "    if (connected_) {"
+        sayCpp "        std::cerr <<"
+        sayCpp "            \"${className}::connectListener: Internal error, already connected.  \""
+        sayCpp "            \"Not connecting again.\\n\" << std::flush;"
+        sayCpp "        return false;"
+        sayCpp "    }"
+        sayCpp "    setParent(source);"
+        sayCpp "    connected_ = connect(source, signal.c_str(), SLOT(invoke(${paramTypeList})));"
+        sayCpp "    return connected_;"
+        sayCpp "}"
+        sayCpp
+        sayCpp "void ${className}::invoke(${paramList}) {"
+        sayCpp "    f_(${paramNameList});"
+        sayCpp "}"
+    }
+
+    forEachListener writeCpp
+    sayHpp
+    sayHpp '#endif'
+    exec {fhpp}>&- {fcpp}>&-
+    unset fhpp fcpp sayHpp sayCpp writeCpp
+    installGen "$cppDir/listener.hpp"{.new,}
+    installGen "$cppDir/listener.cpp"{.new,}
+fi
+
+#### Generate Haskell binding definitions for the listeners.
+
+if [[ -n $hsDir ]]; then
+    msg "Generating Haskell listener binding definitions."
+    exec {fhs}>"$hsDir/src/Graphics/UI/Qtah/Generator/Interface/Listener.hs.new"
+    say() { echo "$*" >&$fhs; }
+
+    say '---------- GENERATED FILE, EDITS WILL BE LOST ----------'
+    say
+    say 'module Graphics.UI.Qtah.Generator.Interface.Listener where'
+    say
+    say 'import qualified Foreign.Hoppy.Generator.Spec as S'
+    say 'import qualified Foreign.Hoppy.Generator.Types as S'
+    say 'import qualified Foreign.Hoppy.Generator.Std.String as String'
+    say 'import qualified Graphics.UI.Qtah.Generator.Types as T'
+    say 'import qualified Graphics.UI.Qtah.Generator.Interface.Callback as C'
+    say 'import qualified Graphics.UI.Qtah.Generator.Interface.Core.QObject as QObject'
+    say
+    say '{-# ANN module "HLint: ignore Use camelCase" #-}'
+
+    writeHs() {
+        local -r name="${1?}"
+        local -r className="Listener${name}"
+        local -r classVar="c_${className}"
+        local -r callbackVar="cb_${name}Void"
+
+        say
+        say "${classVar} ="
+        say "  S.makeClass (S.ident \"${className}\") Nothing [QObject.c_QObject]"
+        say "  [ S.mkCtor \"new\" [S.callbackT C.${callbackVar}]"
+        say "  , S.mkCtor \"newWithParent\""
+        say "    [S.callbackT C.${callbackVar}, S.ptrT \$ S.objT QObject.c_QObject]"
+        say "  ]"
+        say "  [ S.mkMethod \"connectListener\""
+        say "    [S.ptrT \$ S.objT QObject.c_QObject, S.objT String.c_string] S.boolT"
+        say "  ]"
+    }
+    forEachListener writeHs
+
+    say
+    say "aModule :: T.AModule"
+    say "aModule ="
+    say "  T.AHoppyModule \$"
+    say "  S.addReqIncludes [S.includeLocal \"listener.hpp\"] \$"
+    say "  S.moduleModify' (S.makeModule \"listener\" \"b_listener.hpp\" \"b_listener.cpp\") \$"
+    say "  S.moduleAddExports"
+    cont="["
+    writeHs() {
+        local -r name="${1?}"
+        local -r className="Listener${name}"
+        local -r classVar="c_${className}"
+
+        say "  ${cont} S.ExportClass ${classVar}"
+        if [[ $cont = '[' ]]; then cont=','; fi
+    }
+    forEachListener writeHs
+    say "  ]"
+
+    exec {fhs}>&-
+    unset fhs writeHs
+    installGen "$hsDir/src/Graphics/UI/Qtah/Generator/Interface/Listener.hs"{.new,}
+
+    # Also generate a GHC .hs-boot file for cycles in the module graph around listeners.
+
+    msg "Generating Haskell listener .hs-boot file."
+    exec {fhs}>"$hsDir/src/Graphics/UI/Qtah/Generator/Interface/Listener.hs-boot.new"
+    say() { echo "$*" >&$fhs; }
+
+    say '---------- GENERATED FILE, EDITS WILL BE LOST ----------'
+    say
+    say 'module Graphics.UI.Qtah.Generator.Interface.Listener where'
+    say
+    say 'import Foreign.Hoppy.Generator.Spec (Class)'
+    say
+
+    writeHs() {
+        local -r name="${1?}"
+        local -r className="Listener${name}"
+        local -r classVar="c_${className}"
+
+        say "${classVar} :: Class"
+    }
+    forEachListener writeHs
+
+    exec {fhs}>&-
+    unset fhs writeHs
+    installGen "$hsDir/src/Graphics/UI/Qtah/Generator/Interface/Listener.hs-boot"{.new,}
+fi
diff --git a/src/Graphics/UI/Qtah/Generator/Common.hs b/src/Graphics/UI/Qtah/Generator/Common.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Common.hs
@@ -0,0 +1,72 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+-- | General routines.
+module Graphics.UI.Qtah.Generator.Common (
+  splitOn,
+  fromMaybeM,
+  maybeFail,
+  writeFileIfDifferent,
+  ) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative ((<$>))
+#endif
+import Control.Exception (evaluate)
+import Control.Monad (when)
+import Data.List (findIndex)
+import System.Directory (doesFileExist)
+import System.IO (IOMode (ReadMode), hGetContents, withFile)
+
+-- | Splits a list at elements for which a predicate returns true.  The matching
+-- elements themselves are dropped.
+splitWhen :: (a -> Bool) -> [a] -> [[a]]
+splitWhen _ [] = []
+splitWhen f xs = case findIndex f xs of
+  Just index -> let (term, _:rest) = splitAt index xs
+                in term : splitWhen f rest
+  Nothing -> [xs]
+
+-- | Splits a list on a specified element.
+splitOn :: Eq a => a -> [a] -> [[a]]
+splitOn x = splitWhen (== x)
+
+-- | @fromMaybeM m x = maybe m return x@
+fromMaybeM :: Monad m => m a -> Maybe a -> m a
+fromMaybeM = flip maybe return
+
+-- | @maybeFail s x = maybe (fail s) x@
+maybeFail :: Monad m => String -> Maybe a -> m a
+maybeFail = fromMaybeM . fail
+
+-- | If the file specified does not exist or its contents does not match the
+-- given string, then this writes the string to the file.
+writeFileIfDifferent :: FilePath -> String -> IO ()
+writeFileIfDifferent path newContents = do
+  exists <- doesFileExist path
+  -- We need to read the file strictly, otherwise lazy IO might try to write the
+  -- file while it's still open and locked for reading.
+  doWrite <- if exists
+             then (newContents /=) <$> readStrictly
+             else return True
+  when doWrite $ writeFile path newContents
+  where readStrictly = withFile path ReadMode $ \handle -> do
+            contents <- hGetContents handle
+            _ <- evaluate $ length contents
+            return contents
diff --git a/src/Graphics/UI/Qtah/Generator/Empty.hs b/src/Graphics/UI/Qtah/Generator/Empty.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Empty.hs
@@ -0,0 +1,18 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Empty () where
diff --git a/src/Graphics/UI/Qtah/Generator/Flag.hs b/src/Graphics/UI/Qtah/Generator/Flag.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Flag.hs
@@ -0,0 +1,35 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+-- | Utilities for conditional compilation of parts of Qt interfaces.
+module Graphics.UI.Qtah.Generator.Flag (
+  collect,
+  just,
+  test,
+  ) where
+
+import Data.Maybe (catMaybes)
+
+collect :: [Maybe a] -> [a]
+collect = catMaybes
+
+just :: a -> Maybe a
+just = Just
+
+test :: Bool -> a -> Maybe a
+test True = Just
+test False = const Nothing
diff --git a/src/Graphics/UI/Qtah/Generator/Flags.hs b/src/Graphics/UI/Qtah/Generator/Flags.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Flags.hs
@@ -0,0 +1,161 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+-- | Haskell definitions for preprocessor flags that Qt uses for conditional
+-- compilation.
+--
+-- A list of flags enabled on your system can be obtained with:
+--
+-- > gcc -dM -E $(pkg-config --cflags QtCore) /usr/include/qt4/Qt/qconfig.h | grep '#define QT'
+--
+-- Using @qglobal.h@ and @#define Q@ provides additional defintions,
+-- e.g. version and windowing system information.
+module Graphics.UI.Qtah.Generator.Flags (
+  Version,
+  qtVersion,
+  keypadNavigation,
+  qdoc,
+  qrealFloat,
+  wsWince,
+  ) where
+
+import Control.Monad (unless)
+import Data.Char (isDigit, isSpace)
+import Data.List (isPrefixOf)
+import Graphics.UI.Qtah.Generator.Common (fromMaybeM, splitOn)
+import System.Directory (findExecutable)
+import System.Environment (lookupEnv)
+import System.Exit (ExitCode (ExitSuccess))
+import System.IO.Unsafe (unsafePerformIO)
+import System.Process (readProcessWithExitCode)
+
+-- | A type synonym for Qt version specifications.  These are just lists of
+-- integers, of length two.  Examples are @[4, 8]@ and @[5, 0]@ to denote
+-- versions 4.8 and 5.0 respectively.  A third component may be used in the
+-- future, if necessary.
+type Version = [Int]
+
+-- | This is initialized at program startup with the version of Qt that the
+-- generator will work with.  This controls which functions and types are made
+-- available in the API.
+--
+-- This is determined the following method:
+--
+-- * If @QTAH_QT=x.y@ is in the environment, then this value will be used.
+--
+-- * Otherwise, if @QTAH_QT=x@ is in the environment, then we query @qmake
+-- -qt=$QTAH_QT -version@ for the version of Qt to use.
+--
+-- * Otherwise, we query @qmake -version@ for the version of Qt to use.  Setting
+-- @QT_SELECT@ in the environment can select a major version of Qt to use.
+--
+-- For more information on @qmake -qt@ and @QT_SELECT@, see @man qtchooser@.
+qtVersion :: Version
+{-# NOINLINE qtVersion #-}
+qtVersion = unsafePerformIO readQtVersion
+
+keypadNavigation :: Bool
+keypadNavigation = False
+
+qdoc :: Bool
+qdoc = False
+
+-- | Whether Qt was configured with qreal=float instead of double.
+qrealFloat :: Bool
+{-# NOINLINE qrealFloat #-}
+qrealFloat = unsafePerformIO $ readBool "QTAH_QREAL_FLOAT" False
+
+wsWince :: Bool
+wsWince = False
+
+-- | Reads a Qt version from the environment variable @QTAH_QT@.  See
+-- 'qtVersion'.
+readQtVersion :: IO Version
+readQtVersion = do
+  maybeStr <- fmap (\x -> case x of
+                      Just "" -> Nothing
+                      _ -> x) $
+              lookupEnv "QTAH_QT"
+  case maybeStr of
+    Just str -> do
+      let strs = splitOn '.' str
+      unless (length strs `elem` [1, 2] && all (\n -> not (null n) && all isDigit n) strs) $
+        fail $ concat
+        ["qtah-generator requires QTAH_QT=x or QTAH_QT=x.y, can't parse value ", show str, "."]
+      let version = map (read :: String -> Int) strs
+      case version of
+        [_, _] -> return version
+        [x] -> queryQmakeQtVersion ["-qt=" ++ show x]
+        _ -> fail $ concat
+             ["qtah-generator: Internal error, incorrect parsing of QTAH_QT value ", show str, "."]
+    Nothing -> queryQmakeQtVersion []
+
+  where queryQmakeQtVersion :: [String] -> IO Version
+        queryQmakeQtVersion extraArgs = do
+          qmakePath <- findQMake
+          let args = extraArgs ++ ["-version"]
+          (exitCode, out, err) <- readProcessWithExitCode qmakePath args ""
+          let qmakeDebugWords =
+                ["  Ran ", show (qmakePath : args), ".\nStdout:\n", out, "\nStderr:\n", err]
+          unless (exitCode == ExitSuccess) $
+            fail $ concat $ "qtah-generator: qmake returned non-zero exit code." : qmakeDebugWords
+
+          let versionLinePrefix = "Using Qt version "
+
+              maybeVersionStrs = do
+                versionLine <- expectSingle $
+                               filter (versionLinePrefix `isPrefixOf`) $
+                               lines out
+                let str = takeWhile (not . isSpace) $ drop (length versionLinePrefix) versionLine
+                    strs = take 2 $ splitOn '.' str
+                if length strs == 2 && all (\n -> not (null n) && all isDigit n) strs
+                  then Just strs
+                  else Nothing
+
+          case maybeVersionStrs of
+            Just strs -> return $ map (read :: String -> Int) strs
+            Nothing ->
+              fail $ concat $
+              "qtah-generator: Can't parse Qt version from qmake output." : qmakeDebugWords
+
+        expectSingle :: [a] -> Maybe a
+        expectSingle [x] = Just x
+        expectSingle _ = Nothing
+
+-- | Reads a boolean value from the program's environment.  If the variable is
+-- set and non-empty, then if must be one of the strings @true@ or @false@.  An
+-- empty or unset value is treated as the provided default value.
+readBool :: String -> Bool -> IO Bool
+readBool name defaultValue = do
+  maybeStr <- lookupEnv name
+  case maybeStr of
+    Nothing -> return defaultValue
+    Just str -> case str of
+      "" -> return defaultValue
+      "true" -> return True
+      "false" -> return False
+      s -> fail $ concat
+           ["qtah-generator: Expected a boolean value for ", name,
+            " (true/false).  Got ", show s, "."]
+
+findQMake :: IO FilePath
+findQMake = lookupEnv "QTAH_QMAKE" >>= fromMaybeM findQmake
+  where findQmake =
+          findExecutable "qmake" >>=
+          fromMaybeM
+          (fail $ "qtah-generator: Can't find qmake.  Please ensure qmake " ++
+           "is installed and set QTAH_QMAKE to qmake's path.")
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Callback.hs b/src/Graphics/UI/Qtah/Generator/Interface/Callback.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Callback.hs
@@ -0,0 +1,136 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Callback where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportCallback),
+  makeCallback,
+  makeModule,
+  moduleAddExports,
+  moduleModify',
+  toExtName,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, doubleT, enumT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import {-# SOURCE #-} qualified Graphics.UI.Qtah.Generator.Interface.Gui.QClipboard as QClipboard
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton (
+  c_QAbstractButton,
+  )
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSlider (
+  e_SliderAction,
+  )
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Widgets.QAction (c_QAction)
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AHoppyModule $
+  moduleModify' (makeModule "callback" "b_callback.hpp" "b_callback.cpp") $
+  moduleAddExports
+  [ ExportCallback cb_BoolVoid
+  , ExportCallback cb_DoubleVoid
+  , ExportCallback cb_IntVoid
+  , ExportCallback cb_IntBoolVoid
+  , ExportCallback cb_IntIntVoid
+  , ExportCallback cb_PtrQAbstractButtonVoid
+  , ExportCallback cb_PtrQAbstractButtonBoolVoid
+  , ExportCallback cb_PtrQActionVoid
+  , ExportCallback cb_PtrQObjectPtrQEventBool
+  , ExportCallback cb_PtrQObjectVoid
+  , ExportCallback cb_PtrQWidgetPtrQWidgetVoid
+  , ExportCallback cb_QAbstractSliderActionVoid
+  , ExportCallback cb_QClipboardModeVoid
+  , ExportCallback cb_QPointVoid
+  , ExportCallback cb_QSizeVoid
+  , ExportCallback cb_QStringVoid
+  , ExportCallback cb_Void
+  ]
+
+cb_BoolVoid =
+  makeCallback (toExtName "CallbackBoolVoid")
+  [boolT] voidT
+
+cb_DoubleVoid =
+  makeCallback (toExtName "CallbackDoubleVoid")
+  [doubleT] voidT
+
+cb_IntVoid =
+  makeCallback (toExtName "CallbackIntVoid")
+  [intT] voidT
+
+cb_IntBoolVoid =
+  makeCallback (toExtName "CallbackIntBoolVoid")
+  [intT, boolT] voidT
+
+cb_IntIntVoid =
+  makeCallback (toExtName "CallbackIntIntVoid")
+  [intT, intT] voidT
+
+cb_PtrQAbstractButtonVoid =
+  makeCallback (toExtName "CallbackPtrQAbstractButtonVoid")
+  [ptrT $ objT c_QAbstractButton] voidT
+
+cb_PtrQAbstractButtonBoolVoid =
+  makeCallback (toExtName "CallbackPtrQAbstractButtonBoolVoid")
+  [ptrT $ objT c_QAbstractButton, boolT] voidT
+
+cb_PtrQActionVoid =
+  makeCallback (toExtName "CallbackPtrQActionVoid")
+  [ptrT $ objT c_QAction] voidT
+
+cb_PtrQObjectPtrQEventBool =
+  makeCallback (toExtName "CallbackPtrQObjectPtrQEventBool")
+  [ptrT $ objT c_QObject, ptrT $ objT c_QEvent] boolT
+
+cb_PtrQObjectVoid =
+  makeCallback (toExtName "CallbackPtrQObjectVoid")
+  [ptrT $ objT c_QObject] voidT
+
+cb_PtrQWidgetPtrQWidgetVoid =
+  makeCallback (toExtName "CallbackPtrQWidgetPtrQWidgetVoid")
+  [ptrT $ objT c_QWidget, ptrT $ objT c_QWidget] voidT
+
+cb_QAbstractSliderActionVoid =
+  makeCallback (toExtName "CallbackQAbstractSliderActionVoid")
+  [enumT e_SliderAction] voidT
+
+cb_QClipboardModeVoid =
+  makeCallback (toExtName "CallbackQClipboardModeVoid")
+  [enumT QClipboard.e_Mode] voidT
+
+cb_QPointVoid =
+  makeCallback (toExtName "CallbackQPointVoid")
+  [objT c_QPoint] voidT
+
+cb_QSizeVoid =
+  makeCallback (toExtName "CallbackQSizeVoid")
+  [objT c_QSize] voidT
+
+cb_QStringVoid =
+  makeCallback (toExtName "CallbackQStringVoid")
+  [objT c_QString] voidT
+
+cb_Void =
+  makeCallback (toExtName "CallbackVoid")
+  [] voidT
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core.hs
@@ -0,0 +1,68 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Core (modules) where
+
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QChar as QChar
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QChildEvent as QChildEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QCoreApplication as QCoreApplication
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QDir as QDir
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QEvent as QEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QList as QList
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QMargins as QMargins
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QMarginsF as QMarginsF
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QObject as QObject
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QPoint as QPoint
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QPointF as QPointF
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QRect as QRect
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QRectF as QRectF
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QSize as QSize
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QSizeF as QSizeF
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QString as QString
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QStringList as QStringList
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QTimerEvent as QTimerEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.QVector as QVector
+import qualified Graphics.UI.Qtah.Generator.Interface.Core.Types as Types
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+modules :: [AModule]
+modules =
+  concat
+  [ [ QChar.aModule
+    , QChildEvent.aModule
+    , QCoreApplication.aModule
+    , QDir.aModule
+    , QEvent.aModule
+    , QMargins.aModule
+    , QMarginsF.aModule
+    , QObject.aModule
+    , QPoint.aModule
+    , QPointF.aModule
+    , QRect.aModule
+    , QRectF.aModule
+    , QSize.aModule
+    , QSizeF.aModule
+    , QString.aModule
+    , QStringList.aModule
+    , QTimerEvent.aModule
+    , Types.aModule
+    ]
+  , QList.allModules
+  , QVector.allModules
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QChar.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QChar.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QChar.hs
@@ -0,0 +1,278 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QChar (
+  aModule,
+  c_QChar,
+  ) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (
+  addImports,
+  sayLn,
+  )
+import Foreign.Hoppy.Generator.Spec (
+  ClassHaskellConversion (
+    ClassHaskellConversion,
+    classHaskellConversionFromCppFn,
+    classHaskellConversionToCppFn,
+    classHaskellConversionType
+  ),
+  Export (ExportClass, ExportEnum),
+  addReqIncludes,
+  classSetHaskellConversion,
+  hsImport1,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod',
+  mkStaticMethod,
+  mkStaticMethod',
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Comparable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, charT, intT, enumT, objT, refT, ucharT, ushortT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Graphics.UI.Qtah.Generator.Types
+import Language.Haskell.Syntax (
+  HsName (HsIdent),
+  HsQName (UnQual),
+  HsType (HsTyCon),
+  )
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QChar"] $
+  collect
+  [ just $ QtExport $ ExportClass c_QChar
+  , just $ QtExport $ ExportEnum e_Category
+  , just $ QtExport $ ExportEnum e_Decomposition
+  , test (qtVersion < [5, 3]) $ QtExport $ ExportEnum e_Joining
+  , test (qtVersion >= [5, 3]) $ QtExport $ ExportEnum e_JoiningType
+  , just $ QtExport $ ExportEnum e_Direction
+  , just $ QtExport $ ExportEnum e_SpecialCharacter
+  , just $ QtExport $ ExportEnum e_UnicodeVersion
+  ]
+
+-- TODO Add more QChar methods.
+c_QChar =
+  addReqIncludes [includeStd "QChar"] $
+  classAddFeatures [Assignable, Copyable, Comparable, Equatable] $
+  classSetHaskellConversion
+    ClassHaskellConversion
+    { classHaskellConversionType = do
+      addImports importForPrelude
+      return $ HsTyCon $ UnQual $ HsIdent "QtahP.Char"
+    , classHaskellConversionToCppFn = do
+      addImports $ mconcat [hsImport1 "Prelude" "(.)", importForChar, importForRuntime]
+      sayLn "qChar_newFromInt . QtahFHR.coerceIntegral . QtahDC.ord"
+    , classHaskellConversionFromCppFn = do
+      addImports $ mconcat [hsImport1 "Prelude" "(.)", importForChar, importForPrelude,
+                            importForRuntime]
+      sayLn "QtahP.fmap (QtahDC.chr . QtahFHR.coerceIntegral) . qChar_unicode"
+    } $
+  makeClass (ident "QChar") Nothing []
+  [ mkCtor "new" []
+  , mkCtor "newFromCellRow" [ucharT, ucharT]
+  , mkCtor "newFromInt" [intT]
+  , mkCtor "newFromSpecialCharacter" [enumT e_SpecialCharacter]
+  ] $
+  collect
+  [ test (qtVersion < [5]) $ mkStaticMethod' "fromAscii" "newFromAscii" [charT] $ objT c_QChar
+  , just $ mkStaticMethod' "fromLatin1" "newFromLatin1" [charT] $ objT c_QChar
+  , just $ mkConstMethod "category" [] $ enumT e_Category
+  , just $ mkConstMethod "cell" [] ucharT
+  , just $ mkConstMethod "combiningClass" [] ucharT
+  , just $ mkStaticMethod "currentUnicodeVersion" [] $ enumT e_UnicodeVersion
+  , just $ mkConstMethod "decomposition" [] $ objT c_QString
+  , just $ mkConstMethod "decompositionTag" [] $ enumT e_Decomposition
+  , just $ mkConstMethod "digitValue" [] intT
+  , just $ mkConstMethod "direction" [] $ enumT e_Direction
+  , just $ mkConstMethod "hasMirrored" [] boolT
+  , just $ mkConstMethod "isDigit" [] boolT
+  , just $ mkConstMethod "isHighSurrogate" [] boolT
+  , just $ mkConstMethod "isLetter" [] boolT
+  , just $ mkConstMethod "isLetterOrNumber" [] boolT
+  , just $ mkConstMethod "isLowSurrogate" [] boolT
+  , just $ mkConstMethod "isLower" [] boolT
+  , just $ mkConstMethod "isMark" [] boolT
+  , just $ mkConstMethod "isNull" [] boolT
+  , just $ mkConstMethod "isNumber" [] boolT
+  , just $ mkConstMethod "isPrint" [] boolT
+  , just $ mkConstMethod "isPunct" [] boolT
+  , just $ mkConstMethod "isSpace" [] boolT
+  , just $ mkConstMethod "isSymbol" [] boolT
+  , just $ mkConstMethod "isTitleCase" [] boolT
+  , just $ mkConstMethod "isUpper" [] boolT
+  , test (qtVersion < [5, 3]) $ mkConstMethod "joining" [] $ enumT e_Joining
+  , test (qtVersion >= [5, 3]) $ mkConstMethod "joiningType" [] $ enumT e_JoiningType
+  , just $ mkConstMethod "mirroredChar" [] $ objT c_QChar
+  , just $ mkConstMethod "row" [] ucharT
+    -- TODO script (>=5.1)
+  , test (qtVersion < [5]) $ mkConstMethod "toAscii" [] charT
+  , just $ mkConstMethod "toCaseFolded" [] $ objT c_QChar
+  , just $ mkConstMethod "toLatin1" [] charT
+  , just $ mkConstMethod "toLower" [] $ objT c_QChar
+  , just $ mkConstMethod "toTitleCase" [] $ objT c_QChar
+  , just $ mkConstMethod "toUpper" [] $ objT c_QChar
+  , just $ mkConstMethod' "unicode" "unicode" [] ushortT
+  , just $ mkMethod' "unicode" "unicodeRef" [] $ refT ushortT
+  , just $ mkConstMethod "unicodeVersion" [] $ enumT e_UnicodeVersion
+  ]
+
+e_Category =
+  makeQtEnum (ident1 "QChar" "Category") [includeStd "QChar"]
+  [ -- Normative.
+    (1, ["mark", "non", "spacing"])
+  , (2, ["mark", "spacing", "combining"])
+  , (3, ["mark", "enclosing"])
+  , (4, ["number", "decimal", "digit"])
+  , (5, ["number", "letter"])
+  , (6, ["number", "other"])
+  , (7, ["separator", "space"])
+  , (8, ["separator", "line"])
+  , (9, ["separator", "paragraph"])
+  , (10, ["other", "control"])
+  , (11, ["other", "format"])
+  , (12, ["other", "surrogate"])
+  , (13, ["other", "private", "use"])
+  , (14, ["other", "not", "assigned"])
+    -- Informative.
+  , (15, ["letter", "uppercase"])
+  , (16, ["letter", "lowercase"])
+  , (17, ["letter", "titlecase"])
+  , (18, ["letter", "modifier"])
+  , (19, ["letter", "other"])
+  , (20, ["punctuation", "connector"])
+  , (21, ["punctuation", "dash"])
+  , (22, ["punctuation", "open"])
+  , (23, ["punctuation", "close"])
+  , (24, ["punctuation", "initial", "quote"])
+  , (25, ["punctuation", "final", "quote"])
+  , (26, ["punctuation", "other"])
+  , (27, ["symbol", "math"])
+  , (28, ["symbol", "currency"])
+  , (29, ["symbol", "modifier"])
+  , (30, ["symbol", "other"])
+  , (0, ["no", "category"])
+  ]
+
+e_Decomposition =
+  makeQtEnum (ident1 "QChar" "Decomposition") [includeStd "QChar"]
+  [ (0, ["no", "decomposition"])
+  , (1, ["canonical"])
+  , (8, ["circle"])
+  , (16, ["compat"])
+  , (6, ["final"])
+  , (2, ["font"])
+  , (17, ["fraction"])
+  , (4, ["initial"])
+  , (7, ["isolated"])
+  , (5, ["medial"])
+  , (13, ["narrow"])
+  , (3, ["no", "break"])
+  , (14, ["small"])
+  , (15, ["square"])
+  , (10, ["sub"])
+  , (9, ["super"])
+  , (11, ["vertical"])
+  , (12, ["wide"])
+  ]
+
+e_Direction =
+  makeQtEnum (ident1 "QChar" "Direction") [includeStd "QChar"]
+  [ (13, ["dir", "al"])
+  , (5, ["dir", "an"])
+  , (7, ["dir", "b"])
+  , (18, ["dir", "bn"])
+  , (6, ["dir", "cs"])
+  , (2, ["dir", "en"])
+  , (3, ["dir", "es"])
+  , (4, ["dir", "et"])
+  , (0, ["dir", "l"])
+  , (11, ["dir", "lre"])
+  , (12, ["dir", "lro"])
+  , (17, ["dir", "nsm"])
+  , (10, ["dir", "on"])
+  , (16, ["dir", "pdf"])
+  , (1, ["dir", "r"])
+  , (14, ["dir", "rle"])
+  , (15, ["dir", "rlo"])
+  , (8, ["dir", "s"])
+  , (9, ["dir", "ws"])
+  ]
+
+-- | Removed in Qt 5.3.0.
+e_Joining =
+  makeQtEnum (ident1 "QChar" "Joining") [includeStd "QChar"]
+  [ (3, ["center"])
+  , (1, ["dual"])
+  , (0, ["other", "joining"])
+  , (2, ["right"])
+  ]
+
+-- | Since Qt 5.3.0.
+e_JoiningType =
+  makeQtEnum (ident1 "QChar" "JoiningType") [includeStd "QChar"]
+  [ (0, ["joining", "none"])
+  , (1, ["joining", "causing"])
+  , (2, ["joining", "dual"])
+  , (3, ["joining", "right"])
+  , (4, ["joining", "left"])
+  , (5, ["joining", "transparent"])
+  ]
+
+e_SpecialCharacter =
+  makeQtEnum (ident1 "QChar" "SpecialCharacter") [includeStd "QChar"]
+  [ (0x0000, ["null"])
+  , (0x00a0, ["nbsp"])
+  , (0x2028, ["line", "separator"])
+  , (0x2029, ["paragraph", "separator"])
+  , (0xfffc, ["object", "replacement", "character"])
+  , (0xfffd, ["replacement", "character"])
+  , (0xfeff, ["byte", "order", "mark"])
+  , (0xfffe, ["byte", "order", "swapped"])
+  ]
+
+e_UnicodeVersion =
+  makeQtEnum (ident1 "QChar" "UnicodeVersion") [includeStd "QChar"]
+  [ (1, ["unicode", "1_1"])
+  , (2, ["unicode", "2_0"])
+  , (3, ["unicode", "2_1_2"])
+  , (4, ["unicode", "3_0"])
+  , (5, ["unicode", "3_1"])
+  , (6, ["unicode", "3_2"])
+  , (7, ["unicode", "4_0"])
+  , (8, ["unicode", "4_1"])
+  , (9, ["unicode", "5_0"])
+  , (0, ["unicode", "unassigned"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QChildEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QChildEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QChildEvent.hs
@@ -0,0 +1,52 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QChildEvent (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, objT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent, e_Type)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QChildEvent"]
+  [ QtExportEvent c_QChildEvent
+  ]
+
+c_QChildEvent =
+  addReqIncludes [includeStd "QChildEvent"] $
+  makeClass (ident "QChildEvent") Nothing [c_QEvent]
+  [ mkCtor "new" [enumT e_Type, ptrT $ objT c_QObject]
+  ]
+  [ mkConstMethod "added" [] boolT
+  , mkConstMethod "child" [] $ ptrT $ objT c_QObject
+  , mkConstMethod "polished" [] boolT
+  , mkConstMethod "removed" [] boolT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QCoreApplication.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QCoreApplication.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QCoreApplication.hs
@@ -0,0 +1,72 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QCoreApplication (
+  aModule,
+  c_QCoreApplication,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  MethodApplicability (MStatic),
+  Purity (Nonpure),
+  addReqIncludes,
+  ident,
+  ident2,
+  includeLocal,
+  includeStd,
+  makeFnMethod,
+  makeClass,
+  mkStaticMethod,
+  mkStaticMethod',
+  )
+import Foreign.Hoppy.Generator.Types (boolT, intT, objT, ptrT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Core.QStringList (c_QStringList)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QCoreApplication"]
+  [ QtExport $ ExportClass c_QCoreApplication ]
+
+c_QCoreApplication =
+  addReqIncludes [ includeStd "QCoreApplication"
+                 , includeLocal "wrap_qcoreapplication.hpp"
+                 ] $
+  makeClass (ident "QCoreApplication") Nothing [c_QObject]
+  [] $
+  collect
+  [ just $ makeFnMethod (ident2 "qtah" "qcoreapplication" "create") "new" MStatic Nonpure
+    [objT c_QStringList] $ ptrT $ objT c_QCoreApplication
+  , test (qtVersion >= [4, 1]) $ mkStaticMethod "arguments" [] $ objT c_QStringList
+  , just $ mkStaticMethod "exec" [] voidT
+  , just $ mkStaticMethod "exit" [intT] voidT
+  , just $ mkStaticMethod' "instance" "getInstance" [] $ ptrT $ objT c_QCoreApplication
+  , test (qtVersion >= [4, 3]) $ mkStaticMethod' "postEvent" "postEvent"
+    [ptrT $ objT c_QObject, ptrT $ objT c_QEvent] voidT
+  , test (qtVersion >= [4, 3]) $ mkStaticMethod' "postEvent" "postEventWithPriority"
+    [ptrT $ objT c_QObject, ptrT $ objT c_QEvent, intT] voidT
+  , just $ mkStaticMethod "quit" [] voidT
+  , just $ mkStaticMethod "sendEvent" [ptrT $ objT c_QObject, ptrT $ objT c_QEvent] boolT
+    -- TODO Other methods.
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QDir.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QDir.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QDir.hs
@@ -0,0 +1,185 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QDir (
+  aModule,
+  c_QDir,
+  e_Filter,
+  bs_Filters,
+  e_SortFlag,
+  bs_SortFlags,
+  ) where
+
+import Data.Bits ((.|.))
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportBitspace, ExportEnum, ExportClass),
+  Operator (OpArray),
+  addReqIncludes,
+  classSetConversionToGc,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  mkStaticMethod,
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, intT, objT, refT, voidT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QChar (c_QChar)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QDir"]
+  [ QtExport $ ExportClass c_QDir
+  , QtExport $ ExportEnum e_Filter
+  , QtExport $ ExportBitspace bs_Filters
+  , QtExport $ ExportEnum e_SortFlag
+  , QtExport $ ExportBitspace bs_SortFlags
+  ]
+
+c_QDir =
+  addReqIncludes [includeStd "QDir"] $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  classSetConversionToGc $
+  makeClass (ident "QDir") Nothing []
+  [ mkCtor "new" [objT c_QString]
+  ] $
+  collect
+  [ just $ mkConstMethod "absoluteFilePath" [objT c_QString] $ objT c_QString
+  , just $ mkConstMethod "absolutePath" [] $ objT c_QString
+  , test (qtVersion >= [4, 3]) $
+    mkStaticMethod "addSearchPath" [objT c_QString, objT c_QString] voidT
+  , just $ mkConstMethod "canonicalPath" [] $ objT c_QString
+  , just $ mkMethod "cd" [objT c_QString] boolT
+  , just $ mkMethod "cdUp" [] boolT
+  , just $ mkStaticMethod "cleanPath" [objT c_QString] $ objT c_QString
+  , just $ mkConstMethod "count" [] intT
+  , just $ mkStaticMethod "current" [] $ objT c_QDir
+  , just $ mkStaticMethod "currentPath" [] $ objT c_QString
+  , just $ mkConstMethod "dirName" [] $ objT c_QString
+    -- TODO drives
+    -- TODO entryInfoList
+    -- TODO entryList
+  , just $ mkConstMethod' "exists" "exists" [] boolT
+  , just $ mkConstMethod' "exists" "entryExists" [objT c_QString] boolT
+  , just $ mkConstMethod "filePath" [objT c_QString] $ objT c_QString
+  , test (qtVersion >= [4, 2]) $
+    mkStaticMethod "fromNativeSeparators" [objT c_QString] $ objT c_QString
+  , just $ mkStaticMethod "home" [] $ objT c_QDir
+  , just $ mkStaticMethod "homePath" [] $ objT c_QString
+  , just $ mkConstMethod "isAbsolute" [] boolT
+  , just $ mkStaticMethod "isAbsolutePath" [objT c_QString] boolT
+  , just $ mkConstMethod "isReadable" [] boolT
+  , just $ mkConstMethod "isRelative" [] boolT
+  , just $ mkStaticMethod "isRelativePath" [objT c_QString] boolT
+  , just $ mkConstMethod "isRoot" [] boolT
+  , just $ mkMethod "makeAbsolute" [] boolT
+  , just $ mkStaticMethod "match" [objT c_QString, objT c_QString] boolT
+    -- TODO match(QStringList, QString)
+  , just $ mkConstMethod "mkdir" [objT c_QString] boolT
+  , just $ mkConstMethod "mkpath" [objT c_QString] boolT
+  , just $ mkMethod "refresh" [] voidT
+  , just $ mkConstMethod "relativeFilePath" [objT c_QString] $ objT c_QString
+  , just $ mkMethod "remove" [objT c_QString] boolT
+  , test (qtVersion >= [5, 0]) $ mkMethod "removeRecursively" [] boolT
+  , just $ mkMethod "rename" [objT c_QString, objT c_QString] boolT
+  , just $ mkConstMethod "rmdir" [objT c_QString] boolT
+  , just $ mkConstMethod "rmpath" [objT c_QString] boolT
+  , just $ mkStaticMethod "root" [] $ objT c_QDir
+  , just $ mkStaticMethod "rootPath" [] $ objT c_QString
+  , just $ mkStaticMethod "separator" [] $ objT c_QChar
+  , just $ mkStaticMethod "setCurrent" [objT c_QString] boolT
+  , test (qtVersion >= [5, 0]) $ mkMethod "swap" [refT $ objT c_QDir] voidT
+  , just $ mkStaticMethod "temp" [] $ objT c_QDir
+  , just $ mkStaticMethod "tempPath" [] $ objT c_QString
+  , test (qtVersion >= [4, 2]) $
+    mkStaticMethod "toNativeSeparators" [objT c_QString] $ objT c_QString
+  , just $ mkConstMethod OpArray [intT] $ objT c_QString
+  ] ++
+  mkProps
+  [ mkProp "filter" $ bitspaceT bs_Filters
+    -- TODO nameFilters
+  , mkProp "path" $ objT c_QString
+    -- TODO searchPaths (>=4.3)
+  , mkProp "sorting" $ bitspaceT bs_SortFlags
+  ]
+
+(e_Filter, bs_Filters) =
+  makeQtEnumBitspace (ident1 "QDir" "Filter") "Filters" [includeStd "QDir"] $
+  let dirs = 0x1
+      allDirs = 0x400
+      files = 0x2
+      drives = 0x4
+      noSymLinks = 0x8
+      noDotAndDotDot = noDot .|. noDotDot
+      noDot = 0x2000
+      noDotDot = 0x4000
+      allEntries = dirs .|. files .|. drives
+      readable = 0x10
+      writable = 0x20
+      executable = 0x40
+      modified = 0x80
+      hidden = 0x100
+      system = 0x200
+      caseSensitive = 0x800
+  in [ (dirs, ["dirs"])
+     , (allDirs, ["all", "dirs"])
+     , (files, ["files"])
+     , (drives, ["drives"])
+     , (noSymLinks, ["no", "sym", "links"])
+     , (noDotAndDotDot, ["no", "dot", "and", "dot", "dot"])
+     , (noDot, ["no", "dot"])
+     , (noDotDot, ["no", "dot", "dot"])
+     , (allEntries, ["all", "entries"])
+     , (readable, ["readable"])
+     , (writable, ["writable"])
+     , (executable, ["executable"])
+     , (modified, ["modified"])
+     , (hidden, ["hidden"])
+     , (system, ["system"])
+     , (caseSensitive, ["case", "sensitive"])
+     ]
+
+(e_SortFlag, bs_SortFlags) =
+  makeQtEnumBitspace (ident1 "QDir" "SortFlag") "SortFlags" [includeStd "QDir"]
+  [ (0x00, ["name"])
+  , (0x01, ["time"])
+  , (0x02, ["size"])
+  , (0x80, ["type"])
+  , (0x03, ["unsorted"])
+    -- QDir::NoSort = -1.  Not sure this is needed (it's used for parameter
+    -- defaults).  Would need to check if negative values work as expected.
+  , (0x04, ["dirs", "first"])
+  , (0x20, ["dirs", "last"])
+  , (0x08, ["reversed"])
+  , (0x10, ["ignore", "case"])
+  , (0x40, ["locale", "aware"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QEvent.hs
@@ -0,0 +1,221 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QEvent (
+  aModule,
+  c_QEvent,
+  e_Type,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkProps,
+  mkStaticMethod',
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, intT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QEvent"]
+  [ QtExportEvent c_QEvent
+  , QtExport $ ExportEnum e_Type
+  ]
+
+c_QEvent =
+  addReqIncludes [includeStd "QEvent"] $
+  makeClass (ident "QEvent") Nothing []
+  [ mkCtor "new" [enumT e_Type]
+  ] $
+  collect
+  [ just $ mkMethod "accept" [] voidT
+  , just $ mkMethod "ignore" [] voidT
+  , test (qtVersion >= [4, 4]) $
+    mkStaticMethod' "registerEventType" "registerEventType" [] intT
+  , test (qtVersion >= [4, 4]) $
+    mkStaticMethod' "registerEventType" "registerEventTypeWithHint" [intT] intT
+  , just $ mkConstMethod "spontaneous" [] boolT
+  , just $ mkConstMethod' "type" "eventType" [] $ enumT e_Type  -- 'type' is a Haskell keyword.
+  ] ++
+  mkProps
+  [ mkBoolIsProp "accepted"
+  ]
+
+e_Type =
+  makeQtEnum (ident1 "QEvent" "Type") [includeStd "QEvent"]
+  [ (0, ["none"])
+  , (114, ["action", "added"])
+  , (113, ["action", "changed"])
+  , (115, ["action", "removed"])
+  , (99, ["activation", "change"])
+  , (121, ["application", "activate"])
+    -- ApplicationActivated is also 121, but is omitted here because Hoppy enums
+    -- can't handle duplicate numbers.
+  , (122, ["application", "deactivate"])
+  , (36, ["application", "font", "change"])
+  , (37, ["application", "layout", "direction", "change"])
+  , (38, ["application", "palette", "change"])
+  , (214, ["application", "state", "change"])
+  , (35, ["application", "window", "icon", "change"])
+  , (68, ["child", "added"])
+  , (69, ["child", "polished"])
+  , (71, ["child", "removed"])
+  , (40, ["clipboard"])
+  , (19, ["close"])
+  , (200, ["close", "software", "input", "panel"])
+  , (178, ["contents", "rect", "change"])
+  , (82, ["context", "menu"])
+  , (183, ["cursor", "change"])
+  , (52, ["deferred", "delete"])
+  , (60, ["drag", "enter"])
+  , (62, ["drag", "leave"])
+  , (61, ["drag", "move"])
+  , (63, ["drop"])
+  , (170, ["dynamic", "property", "change"])
+  , (98, ["enabled", "change"])
+  , (10, ["enter"])
+  , (150, ["enter", "edit", "focus"])
+  , (124, ["enter", "whats", "this", "mode"])
+  , (206, ["expose"])
+  , (116, ["file", "open"])
+  , (8, ["focus", "in"])
+  , (9, ["focus", "out"])
+  , (23, ["focus", "about", "to", "change"])
+  , (97, ["font", "change"])
+  , (198, ["gesture"])
+  , (202, ["gesture", "override"])
+  , (188, ["grab", "keyboard"])
+  , (186, ["grab", "mouse"])
+  , (159, ["graphics", "scene", "context", "menu"])
+  , (164, ["graphics", "scene", "drag", "enter"])
+  , (166, ["graphics", "scene", "drag", "leave"])
+  , (165, ["graphics", "scene", "drag", "move"])
+  , (167, ["graphics", "scene", "drop"])
+  , (163, ["graphics", "scene", "help"])
+  , (160, ["graphics", "scene", "hover", "enter"])
+  , (162, ["graphics", "scene", "hover", "leave"])
+  , (161, ["graphics", "scene", "hover", "move"])
+  , (158, ["graphics", "scene", "mouse", "double", "click"])
+  , (155, ["graphics", "scene", "mouse", "move"])
+  , (156, ["graphics", "scene", "mouse", "press"])
+  , (157, ["graphics", "scene", "mouse", "release"])
+  , (182, ["graphics", "scene", "move"])
+  , (181, ["graphics", "scene", "resize"])
+  , (168, ["graphics", "scene", "wheel"])
+  , (18, ["hide"])
+  , (27, ["hide", "to", "parent"])
+  , (127, ["hover", "enter"])
+  , (128, ["hover", "leave"])
+  , (129, ["hover", "move"])
+  , (96, ["icon", "drag"])
+  , (101, ["icon", "text", "change"])
+  , (83, ["input", "method"])
+  , (207, ["input", "method", "query"])
+  , (169, ["keyboard", "layout", "change"])
+  , (6, ["key", "press"])
+  , (7, ["key", "release"])
+  , (89, ["language", "change"])
+  , (90, ["layout", "direction", "change"])
+  , (76, ["layout", "request"])
+  , (11, ["leave"])
+  , (151, ["leave", "edit", "focus"])
+  , (125, ["leave", "whats", "this", "mode"])
+  , (88, ["locale", "change"])
+  , (176, ["non", "client", "area", "mouse", "button", "dbl", "click"])
+  , (174, ["non", "client", "area", "mouse", "button", "press"])
+  , (175, ["non", "client", "area", "mouse", "button", "release"])
+  , (173, ["non", "client", "area", "mouse", "move"])
+  , (177, ["mac", "size", "change"])
+  , (43, ["meta", "call"])
+  , (102, ["modified", "change"])
+  , (4, ["mouse", "button", "dbl", "click"])
+  , (2, ["mouse", "button", "press"])
+  , (3, ["mouse", "button", "release"])
+  , (5, ["mouse", "move"])
+  , (109, ["mouse", "tracking", "change"])
+  , (13, ["move"])
+  , (197, ["native", "gesture"])
+  , (208, ["orientation", "change"])
+  , (12, ["paint"])
+  , (39, ["palette", "change"])
+  , (131, ["parent", "about", "to", "change"])
+  , (21, ["parent", "change"])
+  , (212, ["platform", "panel"])
+  , (75, ["polish"])
+  , (74, ["polish", "request"])
+  , (123, ["query", "whats", "this"])
+  , (106, ["read", "only", "change"])
+  , (199, ["request", "software", "input", "panel"])
+  , (14, ["resize"])
+  , (204, ["scroll", "prepare"])
+  , (205, ["scroll"])
+  , (117, ["shortcut"])
+  , (51, ["shortcut", "override"])
+  , (17, ["show"])
+  , (26, ["show", "to", "parent"])
+  , (50, ["sock", "act"])
+  , (192, ["state", "machine", "signal"])
+  , (193, ["state", "machine", "wrapped"])
+  , (112, ["status", "tip"])
+  , (100, ["style", "change"])
+  , (87, ["tablet", "move"])
+  , (92, ["tablet", "press"])
+  , (93, ["tablet", "release"])
+  , (94, ["ok", "request"])
+  , (171, ["tablet", "enter", "proximity"])
+  , (172, ["tablet", "leave", "proximity"])
+  , (22, ["thread", "change"])
+  , (1, ["timer"])
+  , (120, ["tool", "bar", "change"])
+  , (110, ["tool", "tip"])
+  , (184, ["tool", "tip", "change"])
+  , (194, ["touch", "begin"])
+  , (209, ["touch", "cancel"])
+  , (196, ["touch", "end"])
+  , (195, ["touch", "update"])
+  , (189, ["ungrab", "keyboard"])
+  , (187, ["ungrab", "mouse"])
+  , (78, ["update", "later"])
+  , (77, ["update", "request"])
+  , (111, ["whats", "this"])
+  , (118, ["whats", "this", "clicked"])
+  , (31, ["wheel"])
+  , (132, ["win", "event", "act"])
+  , (24, ["window", "activate"])
+  , (103, ["window", "blocked"])
+  , (25, ["window", "deactivate"])
+  , (34, ["window", "icon", "change"])
+  , (105, ["window", "state", "change"])
+  , (33, ["window", "title", "change"])
+  , (104, ["window", "unblocked"])
+  , (203, ["win", "id", "change"])
+  , (126, ["z", "order", "change"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QList.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QList.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QList.hs
@@ -0,0 +1,320 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+-- | Bindings for @QList@.
+module Graphics.UI.Qtah.Generator.Interface.Core.QList (
+  -- * Template
+  Options (..),
+  defaultOptions,
+  Contents (..),
+  instantiate,
+  instantiate',
+  toExports,
+  -- * Instantiations
+  allModules,
+  c_QListInt,
+  c_QListQAbstractButton,
+  c_QListQObject,
+  c_QListQString,
+  c_QListQWidget,
+  ) where
+
+import Control.Monad (forM_, when)
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat, mempty)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (
+  HsTypeSide (HsHsSide),
+  addImports,
+  cppTypeToHsTypeAndUse,
+  indent,
+  ln,
+  prettyPrint,
+  sayLn,
+  saysLn,
+  toHsDataTypeName,
+  toHsMethodName',
+  )
+import Foreign.Hoppy.Generator.Spec (
+  Class,
+  ClassHaskellConversion (
+    ClassHaskellConversion,
+    classHaskellConversionFromCppFn,
+    classHaskellConversionToCppFn,
+    classHaskellConversionType
+    ),
+  Constness (Const, Nonconst),
+  Export (ExportClass),
+  Operator (OpAdd, OpArray),
+  Reqs,
+  Type,
+  addReqs,
+  addAddendumHaskell,
+  classSetHaskellConversion,
+  classSetMonomorphicSuperclass,
+  hsImport1,
+  identT,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  reqInclude,
+  toExtName,
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, constT, intT, objT, ptrT, refT, toGcT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton (c_QAbstractButton)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+import Language.Haskell.Syntax (
+  HsQName (Special),
+  HsSpecialCon (HsListCon),
+  HsType (HsTyApp, HsTyCon),
+  )
+
+-- | Options for instantiating the list classes.
+data Options = Options
+  { optListClassFeatures :: [ClassFeature]
+    -- ^ Additional features to add to the @QList@ class.  Lists are always
+    -- 'Assignable' and 'Copyable', but you may want to add 'Equatable' if your
+    -- value type supports it.
+  }
+
+-- | The default options have no additional 'ClassFeature's.
+defaultOptions :: Options
+defaultOptions = Options []
+
+-- | A set of instantiated classes.
+data Contents = Contents
+  { c_QList :: Class  -- ^ @QList\<T>@
+  }
+
+-- | @instantiate className t tReqs@ creates a set of bindings for an
+-- instantiation of @QList@ and associated types (e.g. iterators).  In the
+-- result, the 'c_QList' class has an external name of @className@.
+instantiate :: String -> Type -> Reqs -> Contents
+instantiate listName t tReqs = instantiate' listName t tReqs defaultOptions
+
+-- | 'instantiate' with additional options.
+instantiate' :: String -> Type -> Reqs -> Options -> Contents
+instantiate' listName t tReqs opts =
+  let reqs = mconcat [ tReqs
+                     , reqInclude $ includeStd "QList"
+                     ]
+      features = Assignable : Copyable : optListClassFeatures opts
+      hasReserve = qtVersion >= [4, 7]
+
+      list =
+        addReqs reqs $
+        addAddendumHaskell addendum $
+        classSetHaskellConversion conversion $
+        classAddFeatures features $
+        classSetMonomorphicSuperclass $
+        makeClass (identT "QList" [t]) (Just $ toExtName listName) []
+        [ mkCtor "new" []
+        ] $
+        collect
+        [ just $ mkMethod' "append" "append" [t] voidT
+        , test (qtVersion >= [4, 5]) $ mkMethod' "append" "appendList" [objT list] voidT
+        , just $ mkMethod' OpArray "at" [intT] $ refT t
+        , just $ mkConstMethod' "at" "atConst" [intT] $ refT $ constT t
+          -- OMIT back
+          -- OMIT begin
+        , just $ mkMethod "clear" [] voidT
+        , just $ mkConstMethod "contains" [t] boolT
+          -- OMIT count()
+        , just $ mkConstMethod "count" [t] intT
+        , test (qtVersion >= [4, 5]) $ mkConstMethod "endsWith" [t] boolT
+          -- OMIT erase
+        , just $ mkMethod' "first" "first" [] $ refT t
+        , just $ mkConstMethod' "first" "firstConst" [] $ refT $ constT t
+        , just $ mkConstMethod' OpArray "get" [intT] t
+        , just $ mkConstMethod' "indexOf" "indexOf" [t] intT
+        , just $ mkConstMethod' "indexOf" "indexOfFrom" [t, intT] intT
+        , just $ mkMethod "insert" [intT, t] voidT
+        , just $ mkConstMethod "isEmpty" [] boolT
+        , just $ mkMethod' "last" "last" [] $ refT t
+        , just $ mkConstMethod' "last" "lastConst" [] $ refT $ constT t
+        , just $ mkConstMethod' "lastIndexOf" "lastIndexOf" [t] intT
+        , just $ mkConstMethod' "lastIndexOf" "lastIndexOfFrom" [t, intT] intT
+          -- OMIT length
+        , just $ mkConstMethod' "mid" "mid" [intT] $ toGcT $ objT list
+        , just $ mkConstMethod' "mid" "midLength" [intT, intT] $ toGcT $ objT list
+        , just $ mkMethod "move" [intT, intT] voidT
+        , just $ mkMethod "prepend" [t] voidT
+        , just $ mkMethod "removeAll" [t] intT
+        , just $ mkMethod "removeAt" [intT] voidT
+        , just $ mkMethod "removeFirst" [] voidT
+        , just $ mkMethod "removeLast" [] voidT
+        , test (qtVersion >= [4, 4]) $ mkMethod "removeOne" [t] boolT
+        , just $ mkMethod "replace" [intT, t] voidT
+        , test hasReserve $ mkMethod "reserve" [intT] voidT
+        , just $ mkConstMethod "size" [] intT
+        , test (qtVersion >= [4, 5]) $ mkConstMethod "startsWith" [t] boolT
+        , just $ mkMethod "swap" [intT, intT] voidT
+          -- OMIT swap(QList<T>&)
+        , just $ mkMethod "takeAt" [intT] t
+        , just $ mkMethod "takeFirst" [] t
+        , just $ mkMethod "takeLast" [] t
+          -- TODO toSet
+          -- TODO toStdList
+          -- TODO toVector
+        , just $ mkConstMethod' "value" "value" [intT] t
+        , just $ mkConstMethod' "value" "valueOr" [intT, t] t
+        , just $ mkConstMethod OpAdd [objT list] $ toGcT $ objT list
+        ]
+
+      -- The addendum for the list class contains HasContents and FromContents
+      -- instances.
+      addendum = do
+        addImports $ mconcat [hsImport1 "Prelude" "(-)",
+                              hsImport1 "Control.Monad" "(<=<)",
+                              importForPrelude,
+                              importForRuntime]
+        when hasReserve $
+          addImports $ hsImport1 "Prelude" "($)"
+
+        forM_ [Const, Nonconst] $ \cst -> do
+          let hsDataTypeName = toHsDataTypeName cst list
+          hsValueType <- cppTypeToHsTypeAndUse HsHsSide $ case cst of
+            Const -> constT t
+            Nonconst -> t
+
+          -- Generate const and nonconst HasContents instances.
+          ln
+          saysLn ["instance QtahFHR.HasContents ", hsDataTypeName,
+                  " (", prettyPrint hsValueType, ") where"]
+          indent $ do
+            sayLn "toContents this' = do"
+            indent $ do
+              let listAt = case cst of
+                    Const -> "atConst"
+                    Nonconst -> "at"
+              saysLn ["size' <- ", toHsMethodName' list "size", " this'"]
+              saysLn ["QtahP.mapM (QtahFHR.decode <=< ",
+                      toHsMethodName' list listAt, " this') [0..size'-1]"]
+
+          -- Only generate a nonconst FromContents instance.
+          when (cst == Nonconst) $ do
+            ln
+            saysLn ["instance QtahFHR.FromContents ", hsDataTypeName,
+                    " (", prettyPrint hsValueType, ") where"]
+            indent $ do
+              sayLn "fromContents values' = do"
+              indent $ do
+                saysLn ["list' <- ", toHsMethodName' list "new"]
+                when hasReserve $
+                  saysLn [toHsMethodName' list "reserve",
+                          " list' $ QtahFHR.coerceIntegral $ QtahP.length values'"]
+                saysLn ["QtahP.mapM_ (", toHsMethodName' list "append", " list') values'"]
+                sayLn "QtahP.return list'"
+
+      -- A QList of some type converts into a Haskell list of the corresponding
+      -- type using HasContents/FromContents.
+      conversion =
+        ClassHaskellConversion
+        { classHaskellConversionType = do
+          hsType <- cppTypeToHsTypeAndUse HsHsSide t
+          return $ HsTyApp (HsTyCon $ Special $ HsListCon) hsType
+        , classHaskellConversionToCppFn = do
+          addImports importForRuntime
+          sayLn "QtahFHR.fromContents"
+        , classHaskellConversionFromCppFn = do
+          addImports importForRuntime
+          sayLn "QtahFHR.toContents"
+        }
+
+  in Contents
+     { c_QList = list
+     }
+
+-- | Converts an instantiation into a list of exports to be included in a
+-- module.
+toExports :: Contents -> [QtExport]
+toExports m = map (QtExport . ExportClass . ($ m)) [c_QList]
+
+createModule :: String -> Contents -> QtModule
+createModule name contents = makeQtModule ["Core", "QList", name] $ toExports contents
+
+allModules :: [AModule]
+allModules =
+  map AQtModule
+  [ qmod_Int
+  , qmod_QAbstractButton
+  , qmod_QObject
+  , qmod_QString
+  , qmod_QWidget
+  ]
+
+qmod_Int :: QtModule
+qmod_Int = createModule "Int" contents_Int
+
+contents_Int :: Contents
+contents_Int =
+  instantiate "QListInt" intT mempty
+
+c_QListInt :: Class
+c_QListInt = c_QList contents_Int
+
+qmod_QAbstractButton :: QtModule
+qmod_QAbstractButton = createModule "QAbstractButton" contents_QAbstractButton
+
+contents_QAbstractButton :: Contents
+contents_QAbstractButton = instantiate "QListQAbstractButton" (ptrT $ objT c_QAbstractButton) mempty
+
+c_QListQAbstractButton :: Class
+c_QListQAbstractButton = c_QList contents_QAbstractButton
+
+qmod_QObject :: QtModule
+qmod_QObject = createModule "QObject" contents_QObject
+
+contents_QObject :: Contents
+contents_QObject = instantiate "QListQObject" (ptrT $ objT c_QObject) mempty
+
+c_QListQObject :: Class
+c_QListQObject = c_QList contents_QObject
+
+qmod_QString :: QtModule
+qmod_QString = createModule "QString" contents_QString
+
+contents_QString :: Contents
+contents_QString = instantiate "QListQString" (objT c_QString) mempty
+
+c_QListQString :: Class
+c_QListQString = c_QList contents_QString
+
+qmod_QWidget :: QtModule
+qmod_QWidget = createModule "QWidget" contents_QWidget
+
+contents_QWidget :: Contents
+contents_QWidget = instantiate "QListQWidget" (ptrT $ objT c_QWidget) mempty
+
+c_QListQWidget :: Class
+c_QListQWidget = c_QList contents_QWidget
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QList.hs-boot b/src/Graphics/UI/Qtah/Generator/Interface/Core/QList.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QList.hs-boot
@@ -0,0 +1,27 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+-- | Bindings for @QList@.
+module Graphics.UI.Qtah.Generator.Interface.Core.QList (
+  c_QListQObject,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (Class)
+
+c_QListQObject :: Class
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QMargins.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QMargins.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QMargins.hs
@@ -0,0 +1,140 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QMargins (
+  aModule,
+  c_QMargins,
+  ) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (
+  addImports,
+  indent,
+  sayLn,
+  saysLn,
+  )
+import Foreign.Hoppy.Generator.Spec (
+  ClassHaskellConversion (
+    ClassHaskellConversion,
+    classHaskellConversionFromCppFn,
+    classHaskellConversionToCppFn,
+    classHaskellConversionType
+  ),
+  Export (ExportClass),
+  Operator (OpAddAssign, OpDivideAssign, OpMultiplyAssign, OpSubtractAssign),
+  addReqIncludes,
+  classSetHaskellConversion,
+  hsImports,
+  hsQualifiedImport,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod',
+  mkProp,
+  mkProps,
+  operatorPreferredExtName',
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, intT, objT, refT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (qreal)
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Graphics.UI.Qtah.Generator.Types
+import Language.Haskell.Syntax (
+  HsName (HsIdent),
+  HsQName (UnQual),
+  HsType (HsTyCon),
+  )
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QMargins"]
+  [ QtExport $ ExportClass c_QMargins ]
+
+c_QMargins =
+  addReqIncludes [includeStd "QMargins"] $
+  classSetHaskellConversion
+    ClassHaskellConversion
+    { classHaskellConversionType = do
+      addImports $ hsQualifiedImport "Graphics.UI.Qtah.Core.HMargins" "HMargins"
+      return $ HsTyCon $ UnQual $ HsIdent "HMargins.HMargins"
+    , classHaskellConversionToCppFn = do
+      addImports $ mconcat [hsImports "Control.Applicative" ["(<$>)", "(<*>)"],
+                            hsQualifiedImport "Graphics.UI.Qtah.Core.HMargins" "HMargins"]
+      saysLn ["qMargins_new <$> HMargins.left <*> HMargins.top <*> HMargins.right <*> ",
+              "HMargins.bottom"]
+    , classHaskellConversionFromCppFn = do
+      addImports $ mconcat [hsQualifiedImport "Graphics.UI.Qtah.Core.HMargins" "HMargins",
+                            importForPrelude]
+      sayLn "\\q -> do"
+      indent $ do
+        sayLn "l <- qMargins_left q"
+        sayLn "t <- qMargins_top q"
+        sayLn "r <- qMargins_right q"
+        sayLn "b <- qMargins_bottom q"
+        sayLn "QtahP.return (HMargins.HMargins l t r b)"
+    } $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  makeClass (ident "QMargins") Nothing []
+  [ mkCtor "newNull" []
+  , mkCtor "new" [intT, intT, intT, intT]
+  ] $
+  collect
+  [ just $ mkConstMethod "isNull" [] boolT
+  , test (qtVersion >= [5, 1]) $
+    mkMethod' OpAddAssign (operatorPreferredExtName' OpAddAssign)
+    [objT c_QMargins] $ refT $ objT c_QMargins
+  , test (qtVersion >= [5, 1]) $
+    mkMethod' OpAddAssign (operatorPreferredExtName' OpAddAssign ++ "Int")
+    [intT] $ refT $ objT c_QMargins
+  , test (qtVersion >= [5, 1]) $
+    mkMethod' OpSubtractAssign (operatorPreferredExtName' OpSubtractAssign)
+    [objT c_QMargins] $ refT $ objT c_QMargins
+  , test (qtVersion >= [5, 1]) $
+    mkMethod' OpSubtractAssign (operatorPreferredExtName' OpSubtractAssign ++ "Int")
+    [intT] $ refT $ objT c_QMargins
+  , test (qtVersion >= [5, 1]) $
+    mkMethod' OpMultiplyAssign (operatorPreferredExtName' OpMultiplyAssign)
+    [intT] $ refT $ objT c_QMargins
+  , test (qtVersion >= [5, 1]) $
+    mkMethod' OpMultiplyAssign (operatorPreferredExtName' OpMultiplyAssign ++ "Real")
+    [qreal] $ refT $ objT c_QMargins
+  , test (qtVersion >= [5, 1]) $
+    mkMethod' OpDivideAssign (operatorPreferredExtName' OpDivideAssign)
+    [intT] $ refT $ objT c_QMargins
+  , test (qtVersion >= [5, 1]) $
+    mkMethod' OpDivideAssign (operatorPreferredExtName' OpDivideAssign ++ "Real")
+    [qreal] $ refT $ objT c_QMargins
+  ] ++
+  mkProps
+  [ mkProp "bottom" intT
+  , mkProp "left" intT
+  , mkProp "right" intT
+  , mkProp "top" intT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QMarginsF.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QMarginsF.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QMarginsF.hs
@@ -0,0 +1,82 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QMarginsF (
+  aModule,
+  c_QMarginsF,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  Operator (OpAddAssign, OpDivideAssign, OpMultiplyAssign, OpSubtractAssign),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod',
+  mkProp,
+  mkProps,
+  operatorPreferredExtName',
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, objT, refT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QMargins (c_QMargins)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (qreal)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+minVersion = [5, 3]
+
+aModule =
+  AQtModule $
+  makeQtModuleWithMinVersion ["Core", "QMarginsF"] minVersion
+  [ QtExport $ ExportClass c_QMarginsF ]
+
+c_QMarginsF =
+  addReqIncludes [includeStd "QMarginsF"] $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  makeClass (ident "QMarginsF") Nothing []
+  [ mkCtor "newNull" []
+  , mkCtor "new" [qreal, qreal, qreal, qreal]
+  , mkCtor "newWithMargins" [objT c_QMargins]
+  ] $
+  [ mkConstMethod "isNull" [] boolT
+  , mkMethod' OpAddAssign (operatorPreferredExtName' OpAddAssign)
+    [objT c_QMarginsF] $ refT $ objT c_QMarginsF
+  , mkMethod' OpAddAssign (operatorPreferredExtName' OpAddAssign ++ "Real")
+    [qreal] $ refT $ objT c_QMarginsF
+  , mkMethod' OpSubtractAssign (operatorPreferredExtName' OpSubtractAssign)
+    [objT c_QMarginsF] $ refT $ objT c_QMarginsF
+  , mkMethod' OpSubtractAssign (operatorPreferredExtName' OpSubtractAssign ++ "Real")
+    [qreal] $ refT $ objT c_QMarginsF
+  , mkMethod' OpMultiplyAssign (operatorPreferredExtName' OpMultiplyAssign)
+    [qreal] $ refT $ objT c_QMarginsF
+  , mkMethod' OpDivideAssign (operatorPreferredExtName' OpDivideAssign)
+    [qreal] $ refT $ objT c_QMarginsF
+  ] ++
+  mkProps
+  [ mkProp "bottom" qreal
+  , mkProp "left" qreal
+  , mkProp "right" qreal
+  , mkProp "top" qreal
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QObject.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QObject.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QObject.hs
@@ -0,0 +1,94 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QObject (
+  aModule,
+  c_QObject,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, intT, objT, ptrT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Listener
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Core.QList (c_QListQObject)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QObject"] $
+  [ QtExport $ ExportClass c_QObject
+  ] ++ map QtExportSignal signals
+
+c_QObject =
+  addReqIncludes [includeStd "QObject"] $
+  makeClass (ident "QObject") Nothing []
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QObject]
+  ] $
+  collect
+  [ just $ mkMethod "blockSignals" [boolT] boolT
+  , just $ mkMethod "children" [] $ objT c_QListQObject
+    -- TODO connect
+  , just $ mkMethod "deleteLater" [] voidT
+    -- TODO disconnect
+  , just $ mkMethod "dumpObjectInfo" [] voidT
+  , just $ mkMethod "dumpObjectTree" [] voidT
+    -- TODO dynamicPropertyNames (>=4.2)
+  , just $ mkMethod "event" [ptrT $ objT c_QEvent] boolT
+  , just $ mkMethod "eventFilter" [ptrT $ objT c_QObject, ptrT $ objT c_QEvent] boolT
+    -- TODO findChild
+    -- TODO findChildren
+    -- TODO inherits
+  , just $ mkMethod "installEventFilter" [ptrT $ objT c_QObject] voidT
+  , just $ mkConstMethod "isWidgetType" [] boolT
+  , -- This is a guess on the version bound.
+    test (qtVersion >= [5, 0]) $ mkConstMethod "isWindowType" [] boolT
+  , just $ mkMethod "killTimer" [intT] voidT
+    -- TODO metaObject
+    -- TODO moveToThread
+    -- TODO property
+  , just $ mkMethod "removeEventFilter" [ptrT $ objT c_QObject] voidT
+    -- TODO setProperty
+  , just $ mkConstMethod "signalsBlocked" [] boolT
+  , just $ mkMethod "startTimer" [intT] intT
+    -- TODO thread
+  ] ++
+  mkProps
+  [ mkProp "objectName" $ objT c_QString
+  , mkProp "parent" $ ptrT $ objT c_QObject
+  ]
+
+signals =
+  [ makeSignal c_QObject "destroyed" c_ListenerPtrQObject
+  , makeSignal c_QObject "objectNameChanged" c_ListenerQString
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QPoint.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QPoint.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QPoint.hs
@@ -0,0 +1,121 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QPoint (
+  aModule,
+  c_QPoint,
+  ) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (
+  addImports,
+  indent,
+  sayLn,
+  )
+import Foreign.Hoppy.Generator.Spec (
+  ClassHaskellConversion (
+    ClassHaskellConversion,
+    classHaskellConversionFromCppFn,
+    classHaskellConversionToCppFn,
+    classHaskellConversionType
+  ),
+  Export (ExportClass),
+  Operator (OpAddAssign, OpDivideAssign, OpMultiplyAssign, OpSubtractAssign),
+  addReqIncludes,
+  classSetHaskellConversion,
+  hsImports,
+  hsQualifiedImport,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  mkStaticMethod,
+  operatorPreferredExtName',
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, intT, objT, refT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (qreal)
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Graphics.UI.Qtah.Generator.Types
+import Language.Haskell.Syntax (
+  HsName (HsIdent),
+  HsQName (UnQual),
+  HsType (HsTyCon),
+  )
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QPoint"]
+  [ QtExport $ ExportClass c_QPoint ]
+
+c_QPoint =
+  addReqIncludes [includeStd "QPoint"] $
+  classSetHaskellConversion
+    ClassHaskellConversion
+    { classHaskellConversionType = do
+      addImports $ hsQualifiedImport "Graphics.UI.Qtah.Core.HPoint" "HPoint"
+      return $ HsTyCon $ UnQual $ HsIdent "HPoint.HPoint"
+    , classHaskellConversionToCppFn = do
+      addImports $ mconcat [hsImports "Control.Applicative" ["(<$>)", "(<*>)"],
+                            hsQualifiedImport "Graphics.UI.Qtah.Core.HPoint" "HPoint"]
+      sayLn "qPoint_new <$> HPoint.x <*> HPoint.y"
+    , classHaskellConversionFromCppFn = do
+      addImports $ mconcat [hsQualifiedImport "Graphics.UI.Qtah.Core.HPoint" "HPoint",
+                            importForPrelude]
+      sayLn "\\q -> do"
+      indent $ do
+        sayLn "y <- qPoint_x q"
+        sayLn "x <- qPoint_y q"
+        sayLn "QtahP.return (HPoint.HPoint x y)"
+    } $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  makeClass (ident "QPoint") Nothing []
+  [ mkCtor "newNull" []
+  , mkCtor "new" [intT, intT]
+  ] $
+  collect
+  [ test (qtVersion >= [5, 1]) $ mkStaticMethod "dotProduct" [objT c_QPoint, objT c_QPoint] intT
+  , just $ mkConstMethod "isNull" [] boolT
+  , just $ mkConstMethod "manhattanLength" [] intT
+  , just $ mkMethod OpAddAssign [objT c_QPoint] $ refT $ objT c_QPoint
+  , just $ mkMethod OpSubtractAssign [objT c_QPoint] $ refT $ objT c_QPoint
+  , just $ mkMethod' OpMultiplyAssign (operatorPreferredExtName' OpMultiplyAssign)
+    [intT] $ refT $ objT c_QPoint
+  , just $ mkMethod' OpMultiplyAssign (operatorPreferredExtName' OpMultiplyAssign ++ "Real")
+    [qreal] $ refT $ objT c_QPoint
+  , just $ mkMethod OpDivideAssign [qreal] $ refT $ objT c_QPoint
+  ] ++
+  mkProps
+  [ mkProp "x" intT
+  , mkProp "y" intT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QPointF.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QPointF.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QPointF.hs
@@ -0,0 +1,119 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QPointF (
+  aModule,
+  c_QPointF,
+  ) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (
+  addImports,
+  indent,
+  sayLn,
+  )
+import Foreign.Hoppy.Generator.Spec (
+  ClassHaskellConversion (
+    ClassHaskellConversion,
+    classHaskellConversionFromCppFn,
+    classHaskellConversionToCppFn,
+    classHaskellConversionType
+  ),
+  Export (ExportClass),
+  Operator (OpAddAssign, OpDivideAssign, OpMultiplyAssign, OpSubtractAssign),
+  addReqIncludes,
+  classSetHaskellConversion,
+  hsImports,
+  hsQualifiedImport,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  mkStaticMethod,
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, objT, refT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (qreal)
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Graphics.UI.Qtah.Generator.Types
+import Language.Haskell.Syntax (
+  HsName (HsIdent),
+  HsQName (UnQual),
+  HsType (HsTyCon),
+  )
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QPointF"]
+  [ QtExport $ ExportClass c_QPointF ]
+
+c_QPointF =
+  addReqIncludes [includeStd "QPointF"] $
+  classSetHaskellConversion
+    ClassHaskellConversion
+    { classHaskellConversionType = do
+      addImports $ hsQualifiedImport "Graphics.UI.Qtah.Core.HPointF" "HPointF"
+      return $ HsTyCon $ UnQual $ HsIdent "HPointF.HPointF"
+    , classHaskellConversionToCppFn = do
+      addImports $ mconcat [hsImports "Control.Applicative" ["(<$>)", "(<*>)"],
+                            hsQualifiedImport "Graphics.UI.Qtah.Core.HPointF" "HPointF"]
+      sayLn "qPointF_new <$> HPointF.x <*> HPointF.y"
+    , classHaskellConversionFromCppFn = do
+      addImports $ mconcat [hsQualifiedImport "Graphics.UI.Qtah.Core.HPointF" "HPointF",
+                            importForPrelude]
+      sayLn "\\q -> do"
+      indent $ do
+        sayLn "y <- qPointF_x q"
+        sayLn "x <- qPointF_y q"
+        sayLn "QtahP.return (HPointF.HPointF x y)"
+    } $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  makeClass (ident "QPointF") Nothing []
+  [ mkCtor "newNull" []
+  , mkCtor "new" [qreal, qreal]
+  , mkCtor "newFromPoint" [objT c_QPoint]
+  ] $
+  collect
+  [ test (qtVersion >= [5, 1]) $ mkStaticMethod "dotProduct" [objT c_QPointF, objT c_QPointF] qreal
+  , just $ mkConstMethod "isNull" [] boolT
+  , test (qtVersion >= [4, 6]) $ mkConstMethod "manhattanLength" [] qreal
+  , just $ mkConstMethod "toPoint" [] $ objT c_QPoint
+  , just $ mkMethod OpAddAssign [objT c_QPointF] $ refT $ objT c_QPointF
+  , just $ mkMethod OpSubtractAssign [objT c_QPointF] $ refT $ objT c_QPointF
+  , just $ mkMethod OpMultiplyAssign [qreal] $ refT $ objT c_QPointF
+  , just $ mkMethod OpDivideAssign [qreal] $ refT $ objT c_QPointF
+  ] ++
+  mkProps
+  [ mkProp "x" qreal
+  , mkProp "y" qreal
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QRect.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QRect.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QRect.hs
@@ -0,0 +1,153 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QRect (
+  aModule,
+  c_QRect,
+  ) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (
+  addImports,
+  indent,
+  sayLn,
+  )
+import Foreign.Hoppy.Generator.Spec (
+  ClassHaskellConversion (
+    ClassHaskellConversion,
+    classHaskellConversionFromCppFn,
+    classHaskellConversionToCppFn,
+    classHaskellConversionType
+  ),
+  Export (ExportClass),
+  addReqIncludes,
+  classSetHaskellConversion,
+  hsImports,
+  hsQualifiedImport,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, intT, objT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QMargins (c_QMargins)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Graphics.UI.Qtah.Generator.Types
+import Language.Haskell.Syntax (
+  HsName (HsIdent),
+  HsQName (UnQual),
+  HsType (HsTyCon),
+  )
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QRect"]
+  [ QtExport $ ExportClass c_QRect ]
+
+c_QRect =
+  addReqIncludes [includeStd "QRect"] $
+  classSetHaskellConversion
+    ClassHaskellConversion
+    { classHaskellConversionType = do
+      addImports $ hsQualifiedImport "Graphics.UI.Qtah.Core.HRect" "HRect"
+      return $ HsTyCon $ UnQual $ HsIdent "HRect.HRect"
+    , classHaskellConversionToCppFn = do
+      addImports $ mconcat [hsImports "Control.Applicative" ["(<$>)", "(<*>)"],
+                            hsQualifiedImport "Graphics.UI.Qtah.Core.HRect" "HRect"]
+      sayLn "qRect_newWithRaw <$> HRect.x <*> HRect.y <*> HRect.width <*> HRect.height"
+    , classHaskellConversionFromCppFn = do
+      addImports $ mconcat [hsQualifiedImport "Graphics.UI.Qtah.Core.HRect" "HRect",
+                            importForPrelude]
+      sayLn "\\q -> do"
+      indent $ do
+        sayLn "x <- qRect_x q"
+        sayLn "y <- qRect_y q"
+        sayLn "w <- qRect_width q"
+        sayLn "h <- qRect_height q"
+        sayLn "QtahP.return (HRect.HRect x y w h)"
+    } $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  makeClass (ident "QRect") Nothing []
+  [ mkCtor "newNull" []
+  , mkCtor "newWithPoints" [objT c_QPoint, objT c_QPoint]
+  , mkCtor "newWithPointAndSize" [objT c_QPoint, objT c_QSize]
+  , mkCtor "newWithRaw" [intT, intT, intT, intT]
+  ] $
+  collect
+  [ just $ mkMethod "adjust" [intT, intT, intT, intT] voidT
+  , just $ mkConstMethod "adjusted" [intT, intT, intT, intT] $ objT c_QRect
+  , just $ mkConstMethod "center" [] $ objT c_QPoint
+  , just $ mkConstMethod' "contains" "containsPoint" [objT c_QPoint, boolT] boolT
+  , just $ mkConstMethod' "contains" "containsRect" [objT c_QRect, boolT] boolT
+  , test (qtVersion >= [4, 2]) $ mkConstMethod "intersected" [objT c_QRect] $ objT c_QRect
+  , just $ mkConstMethod "intersects" [objT c_QRect] boolT
+  , just $ mkConstMethod "isEmpty" [] boolT
+  , just $ mkConstMethod "isNull" [] boolT
+  , just $ mkConstMethod "isValid" [] boolT
+  , test (qtVersion >= [5, 1]) $ mkConstMethod "marginsAdded" [objT c_QMargins] $ objT c_QRect
+  , test (qtVersion >= [5, 1]) $ mkConstMethod "marginsRemoved" [objT c_QMargins] $ objT c_QRect
+  , just $ mkMethod "moveBottom" [intT] voidT
+  , just $ mkMethod "moveBottomLeft" [objT c_QPoint] voidT
+  , just $ mkMethod "moveBottomRight" [objT c_QPoint] voidT
+  , just $ mkMethod "moveCenter" [objT c_QPoint] voidT
+  , just $ mkMethod "moveLeft" [intT] voidT
+  , just $ mkMethod "moveRight" [intT] voidT
+  , just $ mkMethod "moveTo" [objT c_QPoint] voidT
+  , just $ mkMethod "moveTop" [intT] voidT
+  , just $ mkMethod "moveTopLeft" [objT c_QPoint] voidT
+  , just $ mkMethod "moveTopRight" [objT c_QPoint] voidT
+  , just $ mkConstMethod "normalized" [] $ objT c_QRect
+  , just $ mkMethod "setCoords" [intT, intT, intT, intT] voidT
+  , just $ mkMethod "setRect" [intT, intT, intT, intT] voidT
+  , just $ mkMethod "translate" [objT c_QPoint] voidT
+  , just $ mkConstMethod "translated" [objT c_QPoint] $ objT c_QRect
+  , test (qtVersion >= [4, 2]) $ mkMethod "united" [objT c_QRect] $ objT c_QRect
+  ] ++
+  mkProps
+  [ mkProp "bottom" intT
+  , mkProp "bottomLeft" $ objT c_QPoint
+  , mkProp "bottomRight" $ objT c_QPoint
+  , mkProp "height" intT
+  , mkProp "left" intT
+  , mkProp "right" intT
+  , mkProp "size" $ objT c_QSize
+  , mkProp "top" intT
+  , mkProp "topLeft" $ objT c_QPoint
+  , mkProp "topRight" $ objT c_QPoint
+  , mkProp "width" intT
+  , mkProp "x" intT
+  , mkProp "y" intT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QRectF.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QRectF.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QRectF.hs
@@ -0,0 +1,115 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QRectF (
+  aModule,
+  c_QRectF,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  classSetConversionToGc,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, objT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QMarginsF (c_QMarginsF)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPointF (c_QPointF)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSizeF (c_QSizeF)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (qreal)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QRectF"]
+  [ QtExport $ ExportClass c_QRectF ]
+
+c_QRectF =
+  addReqIncludes [includeStd "QRectF"] $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  classSetConversionToGc $
+  makeClass (ident "QRectF") Nothing []
+  (collect
+   [ just $ mkCtor "newNull" []
+   , test (qtVersion >= [4, 3]) $ mkCtor "newFromPoints" [objT c_QPointF, objT c_QPointF]
+   , just $ mkCtor "newWithPointAndSize" [objT c_QPointF, objT c_QSizeF]
+   , just $ mkCtor "newWithRect" [objT c_QRect]
+   , just $ mkCtor "newWithRaw" [qreal, qreal, qreal, qreal]
+   ]) $
+  collect
+  [ just $ mkMethod "adjust" [qreal, qreal, qreal, qreal] voidT
+  , just $ mkConstMethod "adjusted" [qreal, qreal, qreal, qreal] $ objT c_QRectF
+  , just $ mkConstMethod "center" [] $ objT c_QPointF
+  , just $ mkConstMethod' "contains" "containsPoint" [objT c_QPointF] boolT
+  , just $ mkConstMethod' "contains" "containsRect" [objT c_QRectF] boolT
+  , test (qtVersion >= [4, 2]) $ mkConstMethod "intersected" [objT c_QRectF] $ objT c_QRectF
+  , just $ mkConstMethod "intersects" [objT c_QRectF] boolT
+  , just $ mkConstMethod "isEmpty" [] boolT
+  , just $ mkConstMethod "isNull" [] boolT
+  , just $ mkConstMethod "isValid" [] boolT
+  , test (qtVersion >= [5, 3]) $ mkConstMethod "marginsAdded" [objT c_QMarginsF] $ objT c_QRectF
+  , test (qtVersion >= [5, 3]) $ mkConstMethod "marginsRemoved" [objT c_QMarginsF] $ objT c_QRectF
+  , just $ mkMethod "moveBottom" [qreal] voidT
+  , just $ mkMethod "moveBottomLeft" [objT c_QPointF] voidT
+  , just $ mkMethod "moveBottomRight" [objT c_QPointF] voidT
+  , just $ mkMethod "moveCenter" [objT c_QPointF] voidT
+  , just $ mkMethod "moveLeft" [qreal] voidT
+  , just $ mkMethod "moveRight" [qreal] voidT
+  , just $ mkMethod "moveTo" [objT c_QPointF] voidT
+  , just $ mkMethod "moveTop" [qreal] voidT
+  , just $ mkMethod "moveTopLeft" [objT c_QPointF] voidT
+  , just $ mkMethod "moveTopRight" [objT c_QPointF] voidT
+  , just $ mkConstMethod "normalized" [] $ objT c_QRectF
+  , just $ mkMethod "setCoords" [qreal, qreal, qreal, qreal] voidT
+  , just $ mkMethod "setRect" [qreal, qreal, qreal, qreal] voidT
+  , just $ mkConstMethod "toAlignedRect" [] $ objT c_QRect
+  , just $ mkMethod "translate" [objT c_QPointF] voidT
+  , just $ mkConstMethod "translated" [objT c_QPointF] $ objT c_QRectF
+  , test (qtVersion >= [4, 2]) $ mkMethod "united" [objT c_QRectF] $ objT c_QRectF
+  ] ++
+  mkProps
+  [ mkProp "bottom" qreal
+  , mkProp "bottomLeft" $ objT c_QPointF
+  , mkProp "bottomRight" $ objT c_QPointF
+  , mkProp "height" qreal
+  , mkProp "left" qreal
+  , mkProp "right" qreal
+  , mkProp "size" $ objT c_QSizeF
+  , mkProp "top" qreal
+  , mkProp "topLeft" $ objT c_QPointF
+  , mkProp "topRight" $ objT c_QPointF
+  , mkProp "width" qreal
+  , mkProp "x" qreal
+  , mkProp "y" qreal
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QSize.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QSize.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QSize.hs
@@ -0,0 +1,122 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QSize (
+  aModule,
+  c_QSize,
+  ) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (
+  addImports,
+  indent,
+  sayLn,
+  )
+import Foreign.Hoppy.Generator.Spec (
+  ClassHaskellConversion (
+    ClassHaskellConversion,
+    classHaskellConversionFromCppFn,
+    classHaskellConversionToCppFn,
+    classHaskellConversionType
+  ),
+  Export (ExportClass),
+  Operator (OpAddAssign, OpDivideAssign, OpMultiplyAssign, OpSubtractAssign),
+  addReqIncludes,
+  classSetHaskellConversion,
+  hsImports,
+  hsQualifiedImport,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, intT, objT, refT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_AspectRatioMode, qreal)
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Graphics.UI.Qtah.Generator.Types
+import Language.Haskell.Syntax (
+  HsName (HsIdent),
+  HsQName (UnQual),
+  HsType (HsTyCon),
+  )
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QSize"]
+  [ QtExport $ ExportClass c_QSize ]
+
+c_QSize =
+  addReqIncludes [includeStd "QSize"] $
+  classSetHaskellConversion
+    ClassHaskellConversion
+    { classHaskellConversionType = do
+      addImports $ hsQualifiedImport "Graphics.UI.Qtah.Core.HSize" "HSize"
+      return $ HsTyCon $ UnQual $ HsIdent "HSize.HSize"
+    , classHaskellConversionToCppFn = do
+      addImports $ mconcat [hsImports "Control.Applicative" ["(<$>)", "(<*>)"],
+                            hsQualifiedImport "Graphics.UI.Qtah.Core.HSize" "HSize"]
+      sayLn "qSize_new <$> HSize.width <*> HSize.height"
+    , classHaskellConversionFromCppFn = do
+      addImports $ mconcat [hsQualifiedImport "Graphics.UI.Qtah.Core.HSize" "HSize",
+                            importForPrelude]
+      sayLn "\\q -> do"
+      indent $ do
+        sayLn "w <- qSize_width q"
+        sayLn "h <- qSize_height q"
+        sayLn "QtahP.return (HSize.HSize w h)"
+    } $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  makeClass (ident "QSize") Nothing []
+  [ mkCtor "newNull" []
+  , mkCtor "new" [intT, intT]
+  ] $
+  collect
+  [ just $ mkConstMethod "boundedTo" [objT c_QSize] $ objT c_QSize
+  , just $ mkConstMethod "expandedTo" [objT c_QSize] $ objT c_QSize
+  , just $ mkConstMethod "isEmpty" [] boolT
+  , just $ mkConstMethod "isNull" [] boolT
+  , just $ mkConstMethod "isValid" [] boolT
+  , just $ mkMethod "scale" [objT c_QSize, enumT e_AspectRatioMode] voidT
+  , test (qtVersion >= [5, 0]) $
+    mkConstMethod "scaled" [objT c_QSize, enumT e_AspectRatioMode] $ objT c_QSize
+  , just $ mkMethod "transpose" [] voidT
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "transposed" [] $ objT c_QSize
+  , just $ mkMethod OpAddAssign [objT c_QSize] $ refT $ objT c_QSize
+  , just $ mkMethod OpSubtractAssign [objT c_QSize] $ refT $ objT c_QSize
+  , just $ mkMethod OpMultiplyAssign [qreal] $ refT $ objT c_QSize
+  , just $ mkMethod OpDivideAssign [qreal] $ refT $ objT c_QSize
+  ] ++
+  mkProps
+  [ mkProp "height" intT
+  , mkProp "width" intT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QSizeF.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QSizeF.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QSizeF.hs
@@ -0,0 +1,84 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QSizeF (
+  aModule,
+  c_QSizeF,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  Operator (OpAddAssign, OpDivideAssign, OpMultiplyAssign, OpSubtractAssign),
+  addReqIncludes,
+  classSetConversionToGc,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, objT, refT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_AspectRatioMode, qreal)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QSizeF"]
+  [ QtExport $ ExportClass c_QSizeF ]
+
+c_QSizeF =
+  addReqIncludes [includeStd "QSizeF"] $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  classSetConversionToGc $
+  makeClass (ident "QSizeF") Nothing []
+  [ mkCtor "newNull" []
+  , mkCtor "new" [qreal, qreal]
+  , mkCtor "newWithSize" [objT c_QSize]
+  ] $
+  collect
+  [ just $ mkConstMethod "boundedTo" [objT c_QSizeF] $ objT c_QSizeF
+  , just $ mkConstMethod "expandedTo" [objT c_QSizeF] $ objT c_QSizeF
+  , just $ mkConstMethod "isEmpty" [] boolT
+  , just $ mkConstMethod "isNull" [] boolT
+  , just $ mkConstMethod "isValid" [] boolT
+  , just $ mkMethod "scale" [objT c_QSizeF, enumT e_AspectRatioMode] voidT
+  , test (qtVersion >= [5, 0]) $
+    mkConstMethod "scaled" [objT c_QSizeF, enumT e_AspectRatioMode] $ objT c_QSizeF
+  , just $ mkConstMethod "toSize" [] $ objT c_QSize
+  , just $ mkMethod "transpose" [] voidT
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "transposed" [] $ objT c_QSizeF
+  , just $ mkMethod OpAddAssign [objT c_QSizeF] $ refT $ objT c_QSizeF
+  , just $ mkMethod OpSubtractAssign [objT c_QSizeF] $ objT c_QSizeF
+  , just $ mkMethod OpMultiplyAssign [qreal] $ refT $ objT c_QSizeF
+  , just $ mkMethod OpDivideAssign [qreal] $ refT $ objT c_QSizeF
+  ] ++
+  mkProps
+  [ mkProp "height" qreal
+  , mkProp "width" qreal
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QString.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QString.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QString.hs
@@ -0,0 +1,103 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QString (
+  aModule,
+  c_QString,
+  ) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (
+  addImports,
+  sayLn,
+  )
+import Foreign.Hoppy.Generator.Spec (
+  ClassHaskellConversion (
+    ClassHaskellConversion,
+    classHaskellConversionFromCppFn,
+    classHaskellConversionToCppFn,
+    classHaskellConversionType
+  ),
+  Export (ExportClass),
+  MethodApplicability (MNormal),
+  Operator (OpArray),
+  Purity (Nonpure),
+  addReqIncludes,
+  classSetHaskellConversion,
+  ident,
+  ident2,
+  includeLocal,
+  includeStd,
+  makeClass,
+  makeFnMethod,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Comparable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Std.String (c_string)
+import Foreign.Hoppy.Generator.Types (charT, constT, intT, objT, ptrT, refT, voidT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QChar (c_QChar)
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Graphics.UI.Qtah.Generator.Types
+import Language.Haskell.Syntax (
+  HsName (HsIdent),
+  HsQName (UnQual),
+  HsType (HsTyCon),
+  )
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QString"]
+  [ QtExport $ ExportClass c_QString
+  ]
+
+c_QString =
+  addReqIncludes [includeStd "QString",
+                  includeLocal "wrap_qstring.hpp"] $
+  classAddFeatures [Assignable, Copyable, Comparable, Equatable] $
+  classSetHaskellConversion
+    ClassHaskellConversion
+    { classHaskellConversionType = do
+      addImports importForPrelude
+      return $ HsTyCon $ UnQual $ HsIdent "QtahP.String"
+    , classHaskellConversionToCppFn = do
+      addImports $ mconcat [importForForeignC, importForPrelude]
+      sayLn "QtahP.flip QtahFC.withCString qString_newFromCString"
+    , classHaskellConversionFromCppFn = sayLn "qString_toStdString"
+    } $
+  makeClass (ident "QString") Nothing []
+  [ mkCtor "newFromCString" [ptrT $ constT charT]
+  ] $
+  collect
+  [ just $ mkConstMethod' OpArray "at" [intT] $ objT c_QChar
+  , just $ makeFnMethod (ident2 "qtah" "qstring" "set") "set" MNormal Nonpure
+    [refT $ objT c_QString, intT, objT c_QChar] voidT
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "toHtmlEscaped" [] $ objT c_QString
+  , just $ mkConstMethod "toStdString" [] $ objT c_string
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QString.hs-boot b/src/Graphics/UI/Qtah/Generator/Interface/Core/QString.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QString.hs-boot
@@ -0,0 +1,24 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QString (
+  c_QString,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (Class)
+
+c_QString :: Class
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QStringList.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QStringList.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QStringList.hs
@@ -0,0 +1,142 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QStringList (
+  aModule,
+  c_QStringList,
+  ) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (
+  addImports,
+  indent,
+  ln,
+  sayLn,
+  saysLn,
+  toHsCastMethodName,
+  toHsDataTypeName,
+  toHsMethodName',
+  )
+import Foreign.Hoppy.Generator.Spec (
+  ClassHaskellConversion (
+    ClassHaskellConversion,
+    classHaskellConversionFromCppFn,
+    classHaskellConversionToCppFn,
+    classHaskellConversionType
+  ),
+  Constness (Const, Nonconst),
+  Export (ExportClass),
+  addAddendumHaskell,
+  addReqIncludes,
+  classSetHaskellConversion,
+  hsImport1,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, intT, objT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QChar (c_QChar)
+import Graphics.UI.Qtah.Generator.Interface.Core.QList (c_QListQString)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_CaseSensitivity)
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Graphics.UI.Qtah.Generator.Types
+import Language.Haskell.Syntax (
+  HsName (HsIdent),
+  HsQName (Special, UnQual),
+  HsSpecialCon (HsListCon),
+  HsType (HsTyApp, HsTyCon),
+  )
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QStringList"]
+  [ QtExport $ ExportClass c_QStringList ]
+
+c_QStringList =
+  addReqIncludes [includeStd "QStringList"] $
+  classSetHaskellConversion
+    ClassHaskellConversion
+    { classHaskellConversionType = do
+      addImports importForPrelude
+      return $
+        HsTyApp (HsTyCon $ Special $ HsListCon) $
+        HsTyCon $ UnQual $ HsIdent "QtahP.String"
+    , classHaskellConversionToCppFn = do
+      addImports importForRuntime
+      sayLn "QtahFHR.fromContents"
+    , classHaskellConversionFromCppFn = do
+      addImports importForRuntime
+      sayLn "QtahFHR.toContents"
+    } $
+  addAddendumHaskell addendum $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  makeClass (ident "QStringList") Nothing [c_QListQString]
+  [ mkCtor "new" []
+  ] $
+  collect
+  [ -- TODO Regexp methods.
+    just $ mkConstMethod' "contains" "containsCase" [objT c_QString, enumT e_CaseSensitivity] boolT
+  , just $ mkConstMethod' "filter" "filter" [objT c_QString] $ objT c_QStringList
+  , just $ mkConstMethod' "filter" "filterCase" [objT c_QString, enumT e_CaseSensitivity] $
+    objT c_QStringList
+  , just $ mkConstMethod' "join" "joinString" [objT c_QString] $ objT c_QString
+  , test (qtVersion >= [5, 0]) $ mkConstMethod' "join" "joinChar" [objT c_QChar] $ objT c_QString
+  , test (qtVersion >= [4, 5]) $ mkMethod "removeDuplicates" [] intT
+    -- TODO replaceInStrings.  Ownership?
+  , just $ mkMethod' "sort" "sort" [] voidT
+  , test (qtVersion >= [5, 0]) $ mkMethod' "sort" "sortCase" [enumT e_CaseSensitivity] voidT
+  ]
+
+  where addendum = do
+          let hsDataTypeName = toHsDataTypeName Nonconst c_QStringList
+              hsDataTypeNameConst = toHsDataTypeName Const c_QStringList
+          addImports $ mconcat [hsImport1 "Prelude" "(.)",
+                                importForPrelude,
+                                importForRuntime]
+          ln
+          saysLn ["instance QtahFHR.HasContents ", hsDataTypeNameConst, " QtahP.String where"]
+          indent $
+            saysLn ["toContents = QtahFHR.toContents . ", toHsCastMethodName Const c_QListQString]
+          ln
+          saysLn ["instance QtahFHR.HasContents ", hsDataTypeName, " QtahP.String where"]
+          indent $
+            saysLn ["toContents = QtahFHR.toContents . ", toHsCastMethodName Const c_QStringList]
+          ln
+          saysLn ["instance QtahFHR.FromContents ", hsDataTypeName, " QtahP.String where"]
+          indent $ do
+            sayLn "fromContents strs' = do"
+            indent $ do
+              saysLn ["l' <- ", toHsMethodName' c_QStringList "new"]
+              saysLn ["QtahP.mapM_ (", toHsMethodName' c_QListQString "append", " l') strs'"]
+              sayLn "QtahP.return l'"
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QTimerEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QTimerEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QTimerEvent.hs
@@ -0,0 +1,48 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Core.QTimerEvent (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (intT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Core", "QTimerEvent"]
+  [ QtExportEvent c_QTimerEvent
+  ]
+
+c_QTimerEvent =
+  addReqIncludes [includeStd "QTimerEvent"] $
+  makeClass (ident "QTimerEvent") Nothing [c_QEvent]
+  [ mkCtor "new" [intT]
+  ]
+  [ mkConstMethod "timerId" [] intT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/QVector.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/QVector.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/QVector.hs
@@ -0,0 +1,275 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+-- | Bindings for @QVector@.
+module Graphics.UI.Qtah.Generator.Interface.Core.QVector (
+  -- * Template
+  Options (..),
+  defaultOptions,
+  Contents (..),
+  instantiate,
+  instantiate',
+  toExports,
+  -- * Instantiations
+  allModules,
+  c_QVectorQPoint,
+  c_QVectorQPointF,
+  ) where
+
+import Control.Monad (forM_, when)
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat, mempty)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (
+  HsTypeSide (HsHsSide),
+  addImports,
+  cppTypeToHsTypeAndUse,
+  indent,
+  ln,
+  prettyPrint,
+  sayLn,
+  saysLn,
+  toHsDataTypeName,
+  toHsMethodName',
+  )
+import Foreign.Hoppy.Generator.Spec (
+  Class,
+  Constness (Const, Nonconst),
+  Export (ExportClass),
+  Operator (OpAdd, OpArray),
+  Reqs,
+  Type,
+  addReqs,
+  addAddendumHaskell,
+  classSetMonomorphicSuperclass,
+  hsImport1,
+  hsImports,
+  identT,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  reqInclude,
+  toExtName,
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, constT, intT, objT, ptrT, refT, toGcT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPointF (c_QPointF)
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Graphics.UI.Qtah.Generator.Types
+
+-- | Options for instantiating the vector classes.
+data Options = Options
+  { optVectorClassFeatures :: [ClassFeature]
+    -- ^ Additional features to add to the @QVector@ class.  Vectors are always
+    -- 'Assignable' and 'Copyable', but you may want to add 'Equatable' if your
+    -- value type supports it.
+  }
+
+-- | The default options have no additional 'ClassFeature's.
+defaultOptions :: Options
+defaultOptions = Options []
+
+-- | A set of instantiated classes.
+data Contents = Contents
+  { c_QVector :: Class  -- ^ @QVector\<T>@
+  }
+
+-- | @instantiate className t tReqs@ creates a set of bindings for an
+-- instantiation of @QVector@ and associated types (e.g. iterators).  In the
+-- result, the 'c_QVector' class has an external name of @className@.
+instantiate :: String -> Type -> Reqs -> Contents
+instantiate vectorName t tReqs = instantiate' vectorName t tReqs defaultOptions
+
+-- | 'instantiate' with additional options.
+instantiate' :: String -> Type -> Reqs -> Options -> Contents
+instantiate' vectorName t tReqs opts =
+  let reqs = mconcat [ tReqs
+                     , reqInclude $ includeStd "QVector"
+                     ]
+      features = Assignable : Copyable : optVectorClassFeatures opts
+
+      vector =
+        addReqs reqs $
+        addAddendumHaskell addendum $
+        classAddFeatures features $
+        classSetMonomorphicSuperclass $
+        makeClass (identT "QVector" [t]) (Just $ toExtName vectorName) []
+        [ mkCtor "new" []
+        , mkCtor "newWithSize" [intT]
+        , mkCtor "newWithSizeAndValue" [intT, t]
+        ] $
+        collect
+        [ just $ mkMethod' "append" "append" [t] voidT
+        , test (qtVersion >= [5, 5]) $ mkMethod' "append" "appendVector" [objT vector] voidT
+        , just $ mkMethod' OpArray "at" [intT] $ refT t
+        , just $ mkConstMethod' "at" "atConst" [intT] $ refT $ constT t
+        , just $ mkConstMethod "capacity" [] intT
+          -- OMIT back
+          -- OMIT begin
+          -- OMIT cbegin
+          -- OMIT cend
+        , just $ mkMethod "clear" [] voidT
+          -- OMIT constBegin
+          -- OMIT constData
+          -- OMIT constEnd
+        , just $ mkConstMethod "contains" [t] boolT
+          -- OMIT count()
+        , just $ mkConstMethod "count" [t] intT
+        , just $ mkMethod' "data" "array" [] $ ptrT t
+        , just $ mkConstMethod' "data" "arrayConst" [] $ ptrT $ constT t
+          -- OMIT empty
+        , test (qtVersion >= [4, 5]) $ mkConstMethod "endsWith" [t] boolT
+          -- OMIT erase
+        , just $ mkMethod' "fill" "fill" [t] voidT
+        , just $ mkMethod' "fill" "fillResize" [t, intT] voidT
+        , just $ mkMethod' "first" "first" [] $ refT t
+        , just $ mkConstMethod' "first" "firstConst" [] $ refT $ constT t
+          -- TODO fromList
+          -- TODO fromStdVector
+          -- OMIT front
+        , just $ mkConstMethod' OpArray "get" [intT] t
+        , just $ mkConstMethod' "indexOf" "indexOf" [t] intT
+        , just $ mkConstMethod' "indexOf" "indexOfFrom" [t, intT] intT
+        , just $ mkMethod' "insert" "insert" [intT, t] voidT
+        , just $ mkMethod' "insert" "insertMany" [intT, intT, t] voidT
+        , just $ mkConstMethod "isEmpty" [] boolT
+        , just $ mkMethod' "last" "last" [] $ refT t
+        , just $ mkConstMethod' "last" "lastConst" [] $ refT $ constT t
+        , just $ mkConstMethod' "lastIndexOf" "lastIndexOf" [t] intT
+        , just $ mkConstMethod' "lastIndexOf" "lastIndexOfFrom" [t, intT] intT
+          -- OMIT length
+        , just $ mkConstMethod' "mid" "mid" [intT] $ toGcT $ objT vector
+        , just $ mkConstMethod' "mid" "midLength" [intT, intT] $ toGcT $ objT vector
+          -- OMIT pop_back
+          -- OMIT pop_front
+        , just $ mkMethod "prepend" [t] voidT
+          -- OMIT push_back
+          -- OMIT push_front
+        , just $ mkMethod' "remove" "remove" [intT] voidT
+        , just $ mkMethod' "remove" "removeMany" [intT, intT] voidT
+        , test (qtVersion >= [5, 4]) $ mkMethod "removeAll" [t] intT
+          -- OMIT removeAt
+        , test (qtVersion >= [5, 1]) $ mkMethod "removeFirst" [] voidT
+        , test (qtVersion >= [5, 1]) $ mkMethod "removeLast" [] voidT
+        , test (qtVersion >= [5, 4]) $ mkMethod "removeOne" [t] boolT
+        , just $ mkMethod "replace" [intT, t] voidT
+        , just $ mkMethod "reserve" [intT] voidT
+        , just $ mkMethod "resize" [intT] voidT
+        , just $ mkConstMethod "size" [] intT
+        , just $ mkMethod "squeeze" [] voidT
+        , test (qtVersion >= [4, 5]) $ mkConstMethod "startsWith" [t] boolT
+        , test (qtVersion >= [4, 8]) $ mkMethod "swap" [refT $ objT vector] voidT
+        , test (qtVersion >= [5, 2]) $ mkMethod "takeAt" [intT] t
+        , test (qtVersion >= [5, 1]) $ mkMethod "takeFirst" [] t
+        , test (qtVersion >= [5, 1]) $ mkMethod "takeLast" [] t
+          -- TODO toList
+          -- TODO toStdVector
+        , just $ mkConstMethod' "value" "value" [intT] t
+        , just $ mkConstMethod' "value" "valueOr" [intT, t] t
+        , just $ mkConstMethod OpAdd [objT vector] $ toGcT $ objT vector
+        ]
+
+      -- The addendum for the vector class contains HasContents and FromContents
+      -- instances.
+      addendum = do
+        addImports $ mconcat [hsImports "Prelude" ["($)", "(-)"],
+                              hsImport1 "Control.Monad" "(<=<)",
+                              importForPrelude,
+                              importForRuntime]
+
+        forM_ [Const, Nonconst] $ \cst -> do
+          let hsDataTypeName = toHsDataTypeName cst vector
+          hsValueType <- cppTypeToHsTypeAndUse HsHsSide $ case cst of
+            Const -> constT t
+            Nonconst -> t
+
+          -- Generate const and nonconst HasContents instances.
+          ln
+          saysLn ["instance QtahFHR.HasContents ", hsDataTypeName,
+                  " (", prettyPrint hsValueType, ") where"]
+          indent $ do
+            sayLn "toContents this' = do"
+            indent $ do
+              let vectorAt = case cst of
+                    Const -> "atConst"
+                    Nonconst -> "at"
+              saysLn ["size' <- ", toHsMethodName' vector "size", " this'"]
+              saysLn ["QtahP.mapM (QtahFHR.decode <=< ",
+                      toHsMethodName' vector vectorAt, " this') [0..size'-1]"]
+
+          -- Only generate a nonconst FromContents instance.
+          when (cst == Nonconst) $ do
+            ln
+            saysLn ["instance QtahFHR.FromContents ", hsDataTypeName,
+                    " (", prettyPrint hsValueType, ") where"]
+            indent $ do
+              sayLn "fromContents values' = do"
+              indent $ do
+                saysLn ["vector' <- ", toHsMethodName' vector "new"]
+                saysLn [toHsMethodName' vector "reserve",
+                        " vector' $ QtahFHR.coerceIntegral $ QtahP.length values'"]
+                saysLn ["QtahP.mapM_ (", toHsMethodName' vector "append", " vector') values'"]
+                sayLn "QtahP.return vector'"
+
+  in Contents
+     { c_QVector = vector
+     }
+
+-- | Converts an instantiation into a list of exports to be included in a
+-- module.
+toExports :: Contents -> [QtExport]
+toExports m = map (QtExport . ExportClass . ($ m)) [c_QVector]
+
+createModule :: String -> Contents -> QtModule
+createModule name contents = makeQtModule ["Core", "QVector", name] $ toExports contents
+
+allModules :: [AModule]
+allModules =
+  map AQtModule
+  [ qmod_QPoint
+  , qmod_QPointF
+  ]
+
+qmod_QPoint :: QtModule
+qmod_QPoint = createModule "QPoint" contents_QPoint
+
+contents_QPoint :: Contents
+contents_QPoint = instantiate "QVectorQPoint" (objT c_QPoint) mempty
+
+c_QVectorQPoint :: Class
+c_QVectorQPoint = c_QVector contents_QPoint
+
+qmod_QPointF :: QtModule
+qmod_QPointF = createModule "QPointF" contents_QPointF
+
+contents_QPointF :: Contents
+contents_QPointF = instantiate "QVectorQPointF" (objT c_QPointF) mempty
+
+c_QVectorQPointF :: Class
+c_QVectorQPointF = c_QVector contents_QPointF
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Core/Types.hs b/src/Graphics/UI/Qtah/Generator/Interface/Core/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Core/Types.hs
@@ -0,0 +1,383 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+-- | Top-level bindings and bindings in the @Qt::@ namespace.
+module Graphics.UI.Qtah.Generator.Interface.Core.Types (
+  aModule,
+  qreal,
+  e_AlignmentFlag,
+  bs_Alignment,
+  e_AspectRatioMode,
+  e_CaseSensitivity,
+  e_CheckState,
+  e_Corner,
+  e_CursorMoveStyle,
+  e_EventPriority,
+  e_FillRule,
+  e_FocusReason,
+  e_GlobalColor,
+  e_KeyboardModifier,
+  bs_KeyboardModifiers,
+  e_LayoutDirection,
+  e_MouseButton,
+  bs_MouseButtons,
+  e_MouseEventFlag,
+  bs_MouseEventFlags,
+  e_MouseEventSource,
+  e_NavigationMode,
+  e_Orientation,
+  bs_Orientations,
+  e_ScrollBarPolicy,
+  e_ScrollPhase,
+  e_TextElideMode,
+  e_TextFormat,
+  e_TextInteractionFlag,
+  bs_TextInteractionFlags,
+  e_WindowModality,
+  e_WindowState,
+  bs_WindowStates,
+  e_WindowType,
+  bs_WindowFlags,
+  ) where
+
+import Data.Bits ((.|.))
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportBitspace, ExportEnum, ExportFn),
+  Include,
+  Purity (Nonpure),
+  Type,
+  addReqIncludes,
+  ident1,
+  includeStd,
+  makeFn,
+  )
+import Foreign.Hoppy.Generator.Types (doubleT, floatT, objT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qrealFloat, qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule :: AModule
+aModule = AQtModule $ makeQtModule ["Core", "Types"] exports
+
+exports :: [QtExport]
+exports =
+  QtExportSpecials :
+  (map QtExport . collect)
+  [ just $ ExportEnum e_AlignmentFlag
+  , just $ ExportBitspace bs_Alignment
+  , just $ ExportEnum e_AspectRatioMode
+  , just $ ExportEnum e_CaseSensitivity
+  , just $ ExportEnum e_CheckState
+  , just $ ExportEnum e_Corner
+  , just $ ExportEnum e_CursorMoveStyle
+  , just $ ExportEnum e_EventPriority
+  , just $ ExportEnum e_FillRule
+  , just $ ExportEnum e_FocusReason
+  , just $ ExportEnum e_GlobalColor
+  , just $ ExportEnum e_KeyboardModifier
+  , just $ ExportBitspace bs_KeyboardModifiers
+  , just $ ExportEnum e_LayoutDirection
+  , just $ ExportEnum e_MouseButton
+  , just $ ExportBitspace bs_MouseButtons
+  , test (qtVersion >= e_MouseEventFlag_version) $ ExportEnum e_MouseEventFlag
+  , test (qtVersion >= e_MouseEventFlag_version) $ ExportBitspace bs_MouseEventFlags
+  , test (qtVersion >= e_MouseEventSource_version) $ ExportEnum e_MouseEventSource
+  , just $ ExportEnum e_NavigationMode
+  , just $ ExportEnum e_Orientation
+  , just $ ExportBitspace bs_Orientations
+  , just $ ExportEnum e_ScrollBarPolicy
+  , test (qtVersion >= e_ScrollPhase_version) $ ExportEnum e_ScrollPhase
+  , just $ ExportEnum e_TextElideMode
+  , just $ ExportEnum e_TextFormat
+  , just $ ExportEnum e_TextInteractionFlag
+  , just $ ExportBitspace bs_TextInteractionFlags
+  , just $ ExportEnum e_WindowModality
+  , just $ ExportEnum e_WindowState
+  , just $ ExportBitspace bs_WindowStates
+  , just $ ExportEnum e_WindowType
+  , just $ ExportBitspace bs_WindowFlags
+  , test (qtVersion < [5, 0]) $ ExportFn f_escape
+  ]
+
+qtInclude :: [Include]
+qtInclude = [includeStd "Qt"]
+
+qreal :: Type
+qreal = if qrealFloat then floatT else doubleT
+
+(e_AlignmentFlag, bs_Alignment) =
+  makeQtEnumBitspace (ident1 "Qt" "AlignmentFlag") "Alignment" qtInclude
+  [ -- Horizontal flags.
+    (0x01, ["align", "left"])
+  , (0x02, ["align", "right"])
+  , (0x04, ["align", "h", "center"])
+  , (0x08, ["align", "justify"])
+    -- Vertical flags.
+  , (0x20, ["align", "top"])
+  , (0x40, ["align", "bottom"])
+  , (0x80, ["align", "v", "center"])
+    -- Useful in right-to-left mode.
+  , (0x10, ["align", "absolute"])
+  ]
+
+e_AspectRatioMode =
+  makeQtEnum (ident1 "Qt" "AspectRatioMode") qtInclude
+  [ (0, ["ignore", "aspect", "ratio"])
+  , (1, ["keep", "aspect", "ratio"])
+  , (2, ["keep", "aspect", "ratio", "by", "expanding"])
+  ]
+
+e_CaseSensitivity =
+  makeQtEnum (ident1 "Qt" "CaseSensitivity") qtInclude
+  [ (0, ["case", "insensitive"])
+  , (1, ["case", "sensitive"])
+  ]
+
+e_CheckState =
+  makeQtEnum (ident1 "Qt" "CheckState") qtInclude
+  [ (0, ["unchecked"])
+  , (1, ["partially", "checked"])
+  , (2, ["checked"])
+  ]
+
+e_Corner =
+  makeQtEnum (ident1 "Qt" "Corner") qtInclude
+  [ (0x00000, ["top", "left", "corner"])
+  , (0x00001, ["top", "right", "corner"])
+  , (0x00002, ["bottom", "left", "corner"])
+  , (0x00003, ["bottom", "right", "corner"])
+  ]
+
+e_CursorMoveStyle =
+  makeQtEnum (ident1 "Qt" "CursorMoveStyle") qtInclude
+  [ (0, ["logical", "move", "style"])
+  , (1, ["visual", "move", "style"])
+  ]
+
+e_EventPriority =
+  makeQtEnum (ident1 "Qt" "EventPriority") qtInclude
+  [ (1, ["high", "event", "priority"])
+  , (0, ["normal", "event", "priority"])
+  , (-1, ["low", "event", "priority"])
+  ]
+
+e_FillRule =
+  makeQtEnum (ident1 "Qt" "FillRule") qtInclude
+  [ (0, ["odd", "even", "fill"])
+  , (1, ["winding", "fill"])
+  ]
+
+e_FocusReason =
+  makeQtEnum (ident1 "Qt" "FocusReason") qtInclude
+  [ (0, ["mouse", "focus", "reason"])
+  , (1, ["tab", "focus", "reason"])
+  , (2, ["backtab", "focus", "reason"])
+  , (3, ["active", "window", "focus", "reason"])
+  , (4, ["popup", "focus", "reason"])
+  , (5, ["shortcut", "focus", "reason"])
+  , (6, ["menu", "bar", "focus", "reason"])
+  , (7, ["other", "focus", "reason"])
+  ]
+
+e_GlobalColor =
+  makeQtEnum (ident1 "Qt" "GlobalColor") qtInclude
+  [ (3, ["white"])
+  , (2, ["black"])
+  , (7, ["red"])
+  , (13, ["dark", "red"])
+  , (8, ["green"])
+  , (14, ["dark", "green"])
+  , (9, ["blue"])
+  , (15, ["dark", "blue"])
+  , (10, ["cyan"])
+  , (16, ["dark", "cyan"])
+  , (11, ["magenta"])
+  , (17, ["dark", "magenta"])
+  , (12, ["yellow"])
+  , (18, ["dark", "yellow"])
+  , (5, ["gray"])
+  , (4, ["dark", "gray"])
+  , (6, ["light", "gray"])
+  , (19, ["transparent"])
+  , (0, ["color0"])
+  , (1, ["color1"])
+  ]
+
+(e_KeyboardModifier, bs_KeyboardModifiers) =
+  makeQtEnumBitspace (ident1 "Qt" "KeyboardModifier") "KeyboardModifiers" qtInclude
+  [ (0x00000000, ["no", "modifier"])
+  , (0x02000000, ["shift", "modifier"])
+  , (0x04000000, ["control", "modifier"])
+  , (0x08000000, ["alt", "modifier"])
+  , (0x10000000, ["meta", "modifier"])
+  , (0x20000000, ["keypad", "modifier"])
+  , (0x40000000, ["group", "switch", "modifier"])
+  ]
+
+e_LayoutDirection =
+  makeQtEnum (ident1 "Qt" "LayoutDirection") qtInclude
+  [ (0, ["left", "to", "right"])
+  , (1, ["right", "to", "left"])
+  , (2, ["layout", "direction", "auto"])
+  ]
+
+(e_MouseButton, bs_MouseButtons) =
+  makeQtEnumBitspace (ident1 "Qt" "MouseButton") "MouseButtons" qtInclude
+  [ (0x00000000, ["no", "button"])
+  , (0x07ffffff, ["all", "buttons"])
+  , (0x00000001, ["left", "button"])
+  , (0x00000002, ["right", "button"])
+  , (0x00000004, ["middle", "button"])
+    -- TODO Other mouse buttons.  Lots of synonyms here which Hoppy doesn't support.
+  ]
+
+(e_MouseEventFlag, bs_MouseEventFlags) =
+  makeQtEnumBitspace (ident1 "Qt" "MouseEventFlag") "MouseEventFlags" qtInclude
+  [ (0x01, ["mouse", "event", "created", "double", "click"])
+  ]
+
+e_MouseEventFlag_version = [5, 3]
+
+e_MouseEventSource =
+  makeQtEnum (ident1 "Qt" "MouseEventSource") qtInclude
+  [ (0, ["mouse", "event", "not", "synthesized"])
+  , (1, ["mouse", "event", "synthesized", "by", "system"])
+  , (2, ["mouse", "event", "synthesized", "by", "qt"])
+  ]
+
+e_MouseEventSource_version = [5, 3]
+
+e_NavigationMode =
+  makeQtEnum (ident1 "Qt" "NavigationMode") qtInclude
+  [ (0, ["navigation", "mode", "none"])
+  , (1, ["navigation", "mode", "keypad", "tab", "order"])
+  , (2, ["navigation", "mode", "keypad", "directional"])
+  , (3, ["navigation", "mode", "cursor", "auto"])
+  , (4, ["navigation", "mode", "cursor", "force", "visible"])
+  ]
+
+(e_Orientation, bs_Orientations) =
+  makeQtEnumBitspace (ident1 "Qt" "Orientation") "Orientations" qtInclude
+  [ (1, ["horizontal"])
+  , (2, ["vertical"])
+  ]
+
+e_ScrollBarPolicy =
+  makeQtEnum (ident1 "Qt" "ScrollBarPolicy") qtInclude
+  [ (0, ["scroll", "bar", "as", "needed"])
+  , (1, ["scroll", "bar", "always", "off"])
+  , (2, ["scroll", "bar", "always", "on"])
+  ]
+
+e_ScrollPhase =
+  makeQtEnum (ident1 "Qt" "ScrollPhase") qtInclude
+  [ (1, ["scroll", "begin"])
+  , (2, ["scroll", "update"])
+  , (3, ["scroll", "end"])
+  ]
+
+e_ScrollPhase_version = [5, 2]
+
+e_TextElideMode =
+  makeQtEnum (ident1 "Qt" "TextElideMode") qtInclude
+  [ (0, ["elide", "left"])
+  , (1, ["elide", "right"])
+  , (2, ["elide", "middle"])
+  , (3, ["elide", "none"])
+  ]
+
+e_TextFormat =
+  makeQtEnum (ident1 "Qt" "TextFormat") qtInclude
+  [ (0, ["plain", "text"])
+  , (1, ["rich", "text"])
+  , (2, ["auto", "text"])
+  , (3, ["log", "text"])
+  ]
+
+(e_TextInteractionFlag, bs_TextInteractionFlags) =
+  makeQtEnumBitspace (ident1 "Qt" "TextInteractionFlag") "TextInteractionFlags" qtInclude $
+  let noTextInteraction = 0
+      textSelectableByMouse = 1
+      textSelectableByKeyboard = 2
+      linksAccessibleByMouse = 4
+      linksAccessibleByKeyboard = 8
+      textEditable = 16
+      textEditorInteraction = textSelectableByMouse .|. textSelectableByKeyboard .|. textEditable
+      textBrowserInteraction =
+        textSelectableByMouse .|. linksAccessibleByMouse .|. linksAccessibleByKeyboard
+  in [ (noTextInteraction, ["no", "text", "interaction"])
+     , (textSelectableByMouse, ["text", "selectable", "by", "mouse"])
+     , (textSelectableByKeyboard, ["text", "selectable", "by", "keyboard"])
+     , (linksAccessibleByMouse, ["links", "accessible", "by", "mouse"])
+     , (linksAccessibleByKeyboard, ["links", "accessible", "by", "keyboard"])
+     , (textEditable, ["text", "editable"])
+     , (textEditorInteraction, ["text", "editor", "interaction"])
+     , (textBrowserInteraction, ["text", "browser", "interaction"])
+     ]
+
+e_WindowModality =
+  makeQtEnum (ident1 "Qt" "WindowModality") qtInclude
+  [ (0, ["non", "modal"])
+  , (1, ["window", "modal"])
+  , (2, ["application", "modal"])
+  ]
+
+(e_WindowState, bs_WindowStates) =
+  makeQtEnumBitspace (ident1 "Qt" "WindowState") "WindowStates" qtInclude
+  [ (0x00, ["window", "no", "state"])
+  , (0x01, ["window", "minimized"])
+  , (0x02, ["window", "maximized"])
+  , (0x04, ["window", "full", "screen"])
+  , (0x08, ["window", "active"])
+  ]
+
+(e_WindowType, bs_WindowFlags) =
+  makeQtEnumBitspace (ident1 "Qt" "WindowType") "WindowFlags" qtInclude $
+  let widget = 0x0
+      window = 0x1
+      dialog = 0x2 .|. window
+      sheet = 0x4 .|. window
+      drawer = sheet .|. dialog
+      popup = 0x8 .|. window
+      tool = popup .|. dialog
+      toolTip = popup .|. sheet
+      splashScreen = toolTip .|. dialog
+      desktop = 0x10 .|. window
+      subWindow = 0x12 .|. window
+      foreignWindow = 0x20 .|. window
+      coverWindow = 0x40 .|. window
+  in [ (widget, ["widget"])
+     , (window, ["window"])
+     , (dialog, ["dialog"])
+     , (sheet, ["sheet"])
+     , (drawer, ["drawer"])
+     , (popup, ["popup"])
+     , (tool, ["tool"])
+     , (toolTip, ["tool", "tip"])
+     , (splashScreen, ["splash", "screen"])
+     , (desktop, ["desktop"])
+     , (subWindow, ["sub", "window"])
+     , (foreignWindow, ["foreign", "window"])
+     , (coverWindow, ["cover", "window"])
+     ]
+
+f_escape =
+  addReqIncludes [includeStd "QTextDocument"] $
+  makeFn (ident1 "Qt" "escape") Nothing Nonpure [objT c_QString] $ objT c_QString
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/EventListener.hs b/src/Graphics/UI/Qtah/Generator/Interface/EventListener.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/EventListener.hs
@@ -0,0 +1,47 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.EventListener (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident2,
+  includeLocal,
+  makeClass,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (callbackT, intT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Callback (cb_PtrQObjectPtrQEventBool)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Internal", "EventListener"]
+  [ QtExport $ ExportClass c_EventListener ]
+
+c_EventListener =
+  addReqIncludes [includeLocal "event.hpp"] $
+  makeClass (ident2 "qtah" "event" "EventListener") Nothing [c_QObject]
+  [ mkCtor "new" [callbackT cb_PtrQObjectPtrQEventBool, ptrT intT]
+  ]
+  []
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui.hs
@@ -0,0 +1,66 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui (modules) where
+
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QActionEvent as QActionEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QClipboard as QClipboard
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QCloseEvent as QCloseEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QColor as QColor
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QDoubleValidator as QDoubleValidator
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QEnterEvent as QEnterEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QExposeEvent as QExposeEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QFocusEvent as QFocusEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QHideEvent as QHideEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QHoverEvent as QHoverEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QInputEvent as QInputEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QIntValidator as QIntValidator
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QKeyEvent as QKeyEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QMouseEvent as QMouseEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QPolygon as QPolygon
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QPolygonF as QPolygonF
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QRegion as QRegion
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QShowEvent as QShowEvent
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QValidator as QValidator
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui.QWheelEvent as QWheelEvent
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+modules :: [AModule]
+modules =
+  [ QActionEvent.aModule
+  , QClipboard.aModule
+  , QCloseEvent.aModule
+  , QColor.aModule
+  , QDoubleValidator.aModule
+  , QEnterEvent.aModule
+  , QFocusEvent.aModule
+  , QExposeEvent.aModule
+  , QHideEvent.aModule
+  , QHoverEvent.aModule
+  , QInputEvent.aModule
+  , QIntValidator.aModule
+  , QKeyEvent.aModule
+  , QMouseEvent.aModule
+  , QPolygon.aModule
+  , QPolygonF.aModule
+  , QRegion.aModule
+  , QShowEvent.aModule
+  , QValidator.aModule
+  , QWheelEvent.aModule
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QActionEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QActionEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QActionEvent.hs
@@ -0,0 +1,51 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QActionEvent (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (enumT, objT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAction (c_QAction)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent, e_Type)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QActionEvent"]
+  [ QtExportEvent c_QActionEvent
+  ]
+
+c_QActionEvent =
+  addReqIncludes [includeStd "QActionEvent"] $
+  makeClass (ident "QActionEvent") Nothing [c_QEvent]
+  [ mkCtor "new" [enumT e_Type, ptrT $ objT c_QAction]
+  , mkCtor "newBefore" [enumT e_Type, ptrT $ objT c_QAction]
+  ]
+  [ mkConstMethod "action" [] $ ptrT $ objT c_QAction
+  , mkConstMethod "before" [] $ ptrT $ objT c_QAction
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QClipboard.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QClipboard.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QClipboard.hs
@@ -0,0 +1,96 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QClipboard (
+  aModule,
+  c_QClipboard,
+  e_Mode,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  classSetDtorPrivate,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkMethod',
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, objT, refT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Listener (
+  c_Listener,
+  c_ListenerQClipboardMode,
+  )
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QClipboard"] $
+  (QtExport $ ExportClass c_QClipboard) :
+  map QtExportSignal signals ++
+  [ QtExport $ ExportEnum e_Mode ]
+
+c_QClipboard =
+  addReqIncludes [includeStd "QClipboard"] $
+  classSetDtorPrivate $
+  makeClass (ident "QClipboard") Nothing [c_QObject] [] $
+  collect
+  [ just $ mkMethod' "clear" "clear" [] voidT
+  , just $ mkMethod' "clear" "clearWithMode" [enumT e_Mode] voidT
+    -- TODO image
+    -- TODO mimeData
+  , just $ mkConstMethod "ownsClipboard" [] boolT
+  , test (qtVersion >= [4, 2]) $ mkConstMethod "ownsFindBuffer" [] boolT
+  , just $ mkConstMethod "ownsSelection" [] boolT
+    -- TODO pixmap
+    -- TODO setImage
+    -- TODO setMimeData
+    -- TODO setPixmap
+  , just $ mkMethod' "setText" "setText" [objT c_QString] voidT
+  , just $ mkMethod' "setText" "setTextWithMode" [objT c_QString, enumT e_Mode] voidT
+  , just $ mkConstMethod "supportsFindBuffer" [] boolT
+  , just $ mkConstMethod "supportsSelection" [] boolT
+  , just $ mkConstMethod' "text" "text" [] $ objT c_QString
+  , just $ mkConstMethod' "text" "textWithMode" [enumT e_Mode] $ objT c_QString
+  , just $ mkConstMethod' "text" "textSubtype" [refT $ objT c_QString] $ objT c_QString
+  , just $ mkConstMethod' "text" "textSubtypeWithMode" [refT $ objT c_QString, enumT e_Mode] $
+    objT c_QString
+  ]
+
+signals =
+  collect
+  [ test (qtVersion >= [4, 2]) $ makeSignal c_QClipboard "changed" c_ListenerQClipboardMode
+  , just $ makeSignal c_QClipboard "dataChanged" c_Listener
+  , test (qtVersion >= [4, 2]) $ makeSignal c_QClipboard "findBufferChanged" c_Listener
+  , just $ makeSignal c_QClipboard "selectionChanged" c_Listener
+  ]
+
+e_Mode =
+  makeQtEnum (ident1 "QClipboard" "Mode") [includeStd "QClipboard"]
+  [ (0, ["clipboard"])
+  , (1, ["selection"])
+  , (2, ["find", "buffer"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QClipboard.hs-boot b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QClipboard.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QClipboard.hs-boot
@@ -0,0 +1,26 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QClipboard (
+  e_Mode,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (CppEnum)
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+e_Mode :: CppEnum
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QCloseEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QCloseEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QCloseEvent.hs
@@ -0,0 +1,44 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QCloseEvent (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkCtor,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QCloseEvent"]
+  [ QtExportEvent c_QCloseEvent ]
+
+c_QCloseEvent =
+  addReqIncludes [includeStd "QCloseEvent"] $
+  makeClass (ident "QCloseEvent") Nothing [c_QEvent]
+  [ mkCtor "new" []
+  ]
+  []
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QColor.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QColor.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QColor.hs
@@ -0,0 +1,235 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QColor (
+  aModule,
+  c_QColor,
+  ) where
+
+import Control.Monad (forM_)
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (
+  addImports,
+  indent,
+  sayLn,
+  saysLn,
+  )
+import Foreign.Hoppy.Generator.Spec (
+  ClassHaskellConversion (
+    ClassHaskellConversion,
+    classHaskellConversionFromCppFn,
+    classHaskellConversionToCppFn,
+    classHaskellConversionType
+  ),
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  classSetHaskellConversion,
+  hsImports,
+  hsQualifiedImport,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  mkStaticMethod,
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, intT, objT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.QStringList (c_QStringList)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_GlobalColor, qreal)
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Graphics.UI.Qtah.Generator.Types
+import Language.Haskell.Syntax (
+  HsName (HsIdent),
+  HsQName (UnQual),
+  HsType (HsTyCon),
+  )
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QColor"] $
+  collect
+  [ just $ QtExport $ ExportClass c_QColor
+  , test (qtVersion >= [5, 2]) $ QtExport $ ExportEnum e_NameFormat
+  , just $ QtExport $ ExportEnum e_Spec
+  ]
+
+-- TODO Everything using QRgb.
+c_QColor =
+  addReqIncludes [includeStd "QColor"] $
+  classSetHaskellConversion conversion $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  makeClass (ident "QColor") Nothing []
+  [ mkCtor "new" []
+  , mkCtor "newRgb" [intT, intT, intT]
+  , mkCtor "newRgba" [intT, intT, intT, intT]
+  , mkCtor "newNamedColor" [objT c_QString]
+  , mkCtor "newGlobalColor" [enumT e_GlobalColor]
+  ] $
+  collect
+  [ just $ mkConstMethod "black" [] intT
+  , just $ mkConstMethod "blackF" [] qreal
+  , just $ mkStaticMethod "colorNames" [] $ objT c_QStringList
+  , just $ mkConstMethod "convertTo" [enumT e_Spec] $ objT c_QColor
+  , just $ mkConstMethod "cyan" [] intT
+  , just $ mkConstMethod "cyanF" [] qreal
+  , test (qtVersion >= [4, 3]) $ mkConstMethod' "darker" "darker" [] $ objT c_QColor
+  , test (qtVersion >= [4, 3]) $ mkConstMethod' "darker" "darkerBy" [intT] $ objT c_QColor
+  , test (qtVersion >= [4, 6]) $ mkConstMethod "hslHue" [] intT
+  , test (qtVersion >= [4, 6]) $ mkConstMethod "hslHueF" [] qreal
+  , test (qtVersion >= [4, 6]) $ mkConstMethod "hslSaturation" [] intT
+  , test (qtVersion >= [4, 6]) $ mkConstMethod "hslSaturationF" [] qreal
+  , just $ mkConstMethod "hsvHue" [] intT
+  , just $ mkConstMethod "hsvHueF" [] qreal
+  , just $ mkConstMethod "hsvSaturation" [] intT
+  , just $ mkConstMethod "hsvSaturationF" [] qreal
+  , just $ mkConstMethod "hue" [] intT
+  , just $ mkConstMethod "hueF" [] qreal
+  , just $ mkConstMethod "isValid" [] boolT
+  , test (qtVersion >= [4, 7]) $ mkStaticMethod "isValidColor" [objT c_QString] boolT
+  , test (qtVersion >= [4, 3]) $ mkConstMethod' "lighter" "lighter" [] $ objT c_QColor
+  , test (qtVersion >= [4, 3]) $ mkConstMethod' "lighter" "lighterBy" [intT] $ objT c_QColor
+  , test (qtVersion >= [4, 6]) $ mkConstMethod "lightness" [] intT
+  , test (qtVersion >= [4, 6]) $ mkConstMethod "lightnessF" [] qreal
+  , just $ mkConstMethod "magenta" [] intT
+  , just $ mkConstMethod "magentaF" [] qreal
+  , just $ mkConstMethod' "name" "name" [] $ objT c_QString
+  , test (qtVersion >= [5, 2]) $
+    mkConstMethod' "name" "nameWithFormat" [enumT e_NameFormat] $ objT c_QString
+  , just $ mkConstMethod "saturation" [] intT
+  , just $ mkConstMethod "saturationF" [] qreal
+  , just $ mkMethod' "setCmyk" "setCmyk" [intT, intT, intT, intT] voidT
+  , just $ mkMethod' "setCmyk" "setCmyka" [intT, intT, intT, intT, intT] voidT
+  , just $ mkMethod' "setCmykF" "setCmykF" [qreal, qreal, qreal, qreal] voidT
+  , just $ mkMethod' "setCmykF" "setCmykaF" [qreal, qreal, qreal, qreal, qreal] voidT
+  , test (qtVersion >= [4, 6]) $ mkMethod' "setHsl" "setHsl" [intT, intT, intT] voidT
+  , test (qtVersion >= [4, 6]) $ mkMethod' "setHsl" "setHsla" [intT, intT, intT, intT] voidT
+  , test (qtVersion >= [4, 6]) $ mkMethod' "setHslF" "setHslF" [qreal, qreal, qreal] voidT
+  , test (qtVersion >= [4, 6]) $ mkMethod' "setHslF" "setHslaF" [qreal, qreal, qreal, qreal] voidT
+  , just $ mkMethod' "setHsv" "setHsv" [intT, intT, intT] voidT
+  , just $ mkMethod' "setHsv" "setHsva" [intT, intT, intT, intT] voidT
+  , just $ mkMethod' "setHsvF" "setHsvF" [qreal, qreal, qreal] voidT
+  , just $ mkMethod' "setHsvF" "setHsvaF" [qreal, qreal, qreal, qreal] voidT
+  , just $ mkMethod "setNamedColor" [objT c_QString] voidT
+  , just $ mkMethod' "setRgb" "setRgb" [intT, intT, intT] voidT
+  , just $ mkMethod' "setRgb" "setRgba" [intT, intT, intT, intT] voidT
+  , just $ mkMethod' "setRgbF" "setRgbF" [qreal, qreal, qreal] voidT
+  , just $ mkMethod' "setRgbF" "setRgbaF" [qreal, qreal, qreal, qreal] voidT
+  , just $ mkConstMethod "spec" [] $ enumT e_Spec
+  , just $ mkConstMethod "toCmyk" [] $ objT c_QColor
+  , just $ mkConstMethod "toHsl" [] $ objT c_QColor
+  , just $ mkConstMethod "toHsv" [] $ objT c_QColor
+  , just $ mkConstMethod "toRgb" [] $ objT c_QColor
+  , just $ mkConstMethod "value" [] intT
+  , just $ mkConstMethod "valueF" [] qreal
+  , just $ mkConstMethod "yellow" [] intT
+  , just $ mkConstMethod "yellowF" [] qreal
+  ] ++
+  mkProps
+  [ mkProp "alpha" intT
+  , mkProp "alphaF" qreal
+  , mkProp "blue" intT
+  , mkProp "blueF" qreal
+  , mkProp "green" intT
+  , mkProp "greenF" qreal
+  , mkProp "red" intT
+  , mkProp "redF" qreal
+  ]
+
+  where
+    components =
+      [ ("Invalid", "", [])
+      , ("Rgb", "rgba", ["red", "green", "blue", "alpha"])
+      , ("Cmyk", "cmyka", ["cyan", "magenta", "yellow", "black", "alpha"])
+      , ("Hsl", "hsla", ["hslHue", "hslSaturation", "lightness", "alpha"])
+      , ("Hsv", "hsva", ["hsvHue", "hsvSaturation", "value", "alpha"])
+      ]
+
+    hColorImport = hsQualifiedImport "Graphics.UI.Qtah.Gui.HColor" "HColor"
+
+    conversion =
+      ClassHaskellConversion
+      { classHaskellConversionType = do
+        addImports hColorImport
+        return $ HsTyCon $ UnQual $ HsIdent "HColor.HColor"
+
+      , classHaskellConversionToCppFn = do
+        addImports $ mconcat [importForPrelude,
+                              importForRuntime,
+                              hColorImport]
+        sayLn "\\color' -> do"
+        indent $ do
+          sayLn "this' <- qColor_new"
+          sayLn "case color' of"
+          indent $ forM_ components $ \(spec, letters, _) ->
+            saysLn $ concat
+            [ ["HColor.", spec]
+            , map (\var -> [' ', var, '\'']) letters
+            , if null letters
+              then [" -> QtahP.return ()"]
+              else [" -> qColor_set", spec, "a this'"]
+            , concatMap (\var -> [" (QtahFHR.coerceIntegral ", [var], "')"]) letters
+            ]
+          sayLn "QtahP.return this'"
+
+      , classHaskellConversionFromCppFn = do
+        addImports $ mconcat [hsImports "Prelude" ["($)", "(>>=)"],
+                              importForPrelude,
+                              importForRuntime,
+                              hColorImport]
+        sayLn "\\this' -> qColor_spec this' >>= \\spec' -> case spec' of"
+        indent $ forM_ components $ \(spec, letters, getters) -> do
+          saysLn ["QColorSpec_", spec, " -> do"]
+          indent $ do
+            forM_ (zip letters getters) $ \(var, get) ->
+              saysLn [[var], "' <- QtahP.fmap QtahFHR.coerceIntegral $ qColor_", get, " this'"]
+            saysLn $ ["QtahP.return $ HColor.", spec] ++ map (\var -> [' ', var, '\'']) letters
+      }
+
+-- Introduced in Qt 5.2.
+e_NameFormat =
+  makeQtEnum (ident1 "QColor" "NameFormat") [includeStd "QColor"]
+  [ (0, ["hex", "rgb"])
+  , (1, ["hex", "argb"])
+  ]
+
+e_Spec =
+  makeQtEnum (ident1 "QColor" "Spec") [includeStd "QColor"]
+  [ (0, ["invalid"])
+  , (1, ["rgb"])
+  , (2, ["hsv"])
+  , (3, ["cmyk"])
+  , (4, ["hsl"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QDoubleValidator.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QDoubleValidator.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QDoubleValidator.hs
@@ -0,0 +1,75 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QDoubleValidator (
+  aModule,
+  c_QDoubleValidator,
+  e_Notation,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkCtor,
+  mkMethod',
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (doubleT, enumT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Gui.QValidator (c_QValidator)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QDoubleValidator"] $
+  (map QtExport . collect)
+  [ just $ ExportClass c_QDoubleValidator
+  , test (qtVersion >= [4, 3]) $ ExportEnum e_Notation
+  ]
+
+c_QDoubleValidator =
+  addReqIncludes [includeStd "QDoubleValidator"] $
+  makeClass (ident "QDoubleValidator") Nothing [c_QValidator]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QObject]
+  , mkCtor "newWithOptions" [doubleT, doubleT, intT]
+  , mkCtor "newWithOptionsAndParent" [doubleT, doubleT, intT, ptrT $ objT c_QObject]
+  ] $
+  [ mkMethod' "setRange" "setRange" [doubleT, doubleT] voidT
+  , mkMethod' "setRange" "setRangeAndDecimals" [doubleT, doubleT, intT] voidT
+  ] ++
+  (mkProps . collect)
+  [ just $ mkProp "bottom" doubleT
+  , just $ mkProp "decimals" intT
+  , test (qtVersion >= [4, 3]) $ mkProp "notation" $ enumT e_Notation
+  , just $ mkProp "top" doubleT
+  ]
+
+e_Notation =
+  makeQtEnum (ident1 "QDoubleValidator" "Notation") [includeStd "QDoubleValidator"]
+  [ (0, ["standard", "notation"])
+  , (1, ["scientific", "notation"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QEnterEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QEnterEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QEnterEvent.hs
@@ -0,0 +1,59 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QEnterEvent (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (intT, objT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPointF (c_QPointF)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+minVersion = [5, 0]
+
+aModule =
+  AQtModule $
+  makeQtModuleWithMinVersion ["Gui", "QEnterEvent"] minVersion
+  [ QtExportEvent c_QEnterEvent ]
+
+c_QEnterEvent =
+  addReqIncludes [includeStd "QEnterEvent"] $
+  makeClass (ident "QEnterEvent") Nothing [c_QEvent]
+  [ mkCtor "new" [objT c_QPointF, objT c_QPointF, objT c_QPointF]
+  ]
+  [ mkConstMethod "globalPos" [] $ objT c_QPoint
+  , mkConstMethod "globalX" [] intT
+  , mkConstMethod "globalY" [] intT
+  , mkConstMethod "localPos" [] $ objT c_QPointF
+  , mkConstMethod "pos" [] $ objT c_QPoint
+  , mkConstMethod "screenPos" [] $ objT c_QPointF
+  , mkConstMethod "windowPos" [] $ objT c_QPointF
+  , mkConstMethod "x" [] intT
+  , mkConstMethod "y" [] intT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QExposeEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QExposeEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QExposeEvent.hs
@@ -0,0 +1,50 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QExposeEvent (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (objT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent)
+import Graphics.UI.Qtah.Generator.Interface.Gui.QRegion (c_QRegion)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+minVersion = [5, 0]
+
+aModule =
+  AQtModule $
+  makeQtModuleWithMinVersion ["Gui", "QExposeEvent"] minVersion
+  [ QtExportEvent c_QExposeEvent ]
+
+c_QExposeEvent =
+  addReqIncludes [includeStd "QExposeEvent"] $
+  makeClass (ident "QExposeEvent") Nothing [c_QEvent]
+  [ mkCtor "new" [objT c_QRegion]
+  ]
+  [ mkConstMethod "region" [] $ objT c_QRegion
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QFocusEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QFocusEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QFocusEvent.hs
@@ -0,0 +1,52 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QFocusEvent (
+  aModule,
+  c_QFocusEvent,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent, e_Type)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_FocusReason)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QFocusEvent"]
+  [ QtExportEvent c_QFocusEvent
+  ]
+
+c_QFocusEvent =
+  addReqIncludes [includeStd "QFocusEvent"] $
+  makeClass (ident "QFocusEvent") Nothing [c_QEvent]
+  [ mkCtor "new" [enumT e_Type, enumT e_FocusReason]
+  ] $
+  [ mkConstMethod "gotFocus" [] boolT
+  , mkConstMethod "lostFocus" [] boolT
+  , mkConstMethod "reason" [] $ enumT e_FocusReason
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QHideEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QHideEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QHideEvent.hs
@@ -0,0 +1,46 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QHideEvent (
+  aModule,
+  c_QHideEvent,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkCtor,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QHideEvent"]
+  [ QtExportEvent c_QHideEvent
+  ]
+
+c_QHideEvent =
+  addReqIncludes [includeStd "QHideEvent"] $
+  makeClass (ident "QHideEvent") Nothing [c_QEvent]
+  [ mkCtor "new" []
+  ]
+  []
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QHoverEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QHoverEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QHoverEvent.hs
@@ -0,0 +1,63 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QHoverEvent (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, enumT, objT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent, e_Type)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPointF (c_QPointF)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_KeyboardModifiers)
+import Graphics.UI.Qtah.Generator.Interface.Gui.QInputEvent (c_QInputEvent)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QHoverEvent"]
+  [ QtExportEvent c_QHoverEvent
+  ]
+
+c_QHoverEvent =
+  addReqIncludes [includeStd "QHoverEvent"] $
+  makeClass (ident "QHoverEvent") Nothing
+  [if qtVersion >= [5, 0] then c_QInputEvent else c_QEvent]
+  (collect
+   [ test (qtVersion < [5, 0]) $ mkCtor "new" [enumT e_Type, objT c_QPoint, objT c_QPoint]
+   , test (qtVersion >= [5, 0]) $ mkCtor "new" [enumT e_Type, objT c_QPointF, objT c_QPointF]
+   , test (qtVersion >= [5, 0]) $ mkCtor "newWithModifiers"
+     [enumT e_Type, objT c_QPointF, objT c_QPointF, bitspaceT bs_KeyboardModifiers]
+   ]) $
+  collect
+  [ just $ mkConstMethod "oldPos" [] $ objT c_QPoint
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "oldPosF" [] $ objT c_QPointF
+  , just $ mkConstMethod "pos" [] $ objT c_QPoint
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "posF" [] $ objT c_QPointF
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QInputEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QInputEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QInputEvent.hs
@@ -0,0 +1,52 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QInputEvent (
+  aModule,
+  c_QInputEvent,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, ulongT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_KeyboardModifiers)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QInputEvent"]
+  [ QtExportEvent c_QInputEvent
+  ]
+
+c_QInputEvent =
+  addReqIncludes [includeStd "QInputEvent"] $
+  makeClass (ident "QInputEvent") Nothing [c_QEvent]
+  [] $
+  collect
+  [ just $ mkConstMethod "modifiers" [] $ bitspaceT bs_KeyboardModifiers
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "timestamp" [] ulongT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QIntValidator.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QIntValidator.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QIntValidator.hs
@@ -0,0 +1,59 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QIntValidator (
+  aModule,
+  c_QIntValidator,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Gui.QValidator (c_QValidator)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QIntValidator"] $
+  [ QtExport $ ExportClass c_QIntValidator ]
+
+c_QIntValidator =
+  addReqIncludes [includeStd "QIntValidator"] $
+  makeClass (ident "QIntValidator") Nothing [c_QValidator]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QObject]
+  , mkCtor "newWithOptions" [intT, intT]
+  , mkCtor "newWithOptionsAndParent" [intT, intT, ptrT $ objT c_QObject]
+  ] $
+  [ mkMethod "setRange" [intT, intT] voidT
+  ] ++
+  mkProps
+  [ mkProp "bottom" intT
+  , mkProp "top" intT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QKeyEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QKeyEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QKeyEvent.hs
@@ -0,0 +1,70 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QKeyEvent (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, enumT, intT, objT, ushortT, word32T)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (e_Type)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_KeyboardModifiers)
+import Graphics.UI.Qtah.Generator.Interface.Gui.QInputEvent (c_QInputEvent)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QKeyEvent"]
+  [ QtExportEvent c_QKeyEvent
+  ]
+
+c_QKeyEvent =
+  addReqIncludes [includeStd "QKeyEvent"] $
+  makeClass (ident "QKeyEvent") Nothing [c_QInputEvent]
+  (collect
+   [ just $ mkCtor "new" [enumT e_Type, intT, bitspaceT bs_KeyboardModifiers]
+   , just $ mkCtor "newWithText"
+     [enumT e_Type, intT, bitspaceT bs_KeyboardModifiers, objT c_QString, boolT, ushortT]
+   , test (qtVersion >= [5, 0]) $ mkCtor "newNative"
+     [enumT e_Type, intT, bitspaceT bs_KeyboardModifiers, word32T, word32T, word32T]
+   , test (qtVersion >= [5, 0]) $ mkCtor "newNativeWithText"
+     [enumT e_Type, intT, bitspaceT bs_KeyboardModifiers, word32T, word32T, word32T,
+      objT c_QString, boolT, ushortT]
+   ]) $
+  collect
+  [ just $ mkConstMethod "count" [] intT
+  , just $ mkConstMethod "isAutoRepeat" [] boolT
+  , just $ mkConstMethod "key" [] intT
+    -- TODO matches (>=4.2)
+  , just $ mkConstMethod "modifiers" [] $ bitspaceT bs_KeyboardModifiers
+  , test (qtVersion >= [4, 2]) $ mkConstMethod "nativeModifiers" [] word32T
+  , test (qtVersion >= [4, 2]) $ mkConstMethod "nativeScanCode" [] word32T
+  , test (qtVersion >= [4, 2]) $ mkConstMethod "nativeVirtualKey" [] word32T
+  , just $ mkConstMethod "text" [] $ objT c_QString
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QMouseEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QMouseEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QMouseEvent.hs
@@ -0,0 +1,90 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QMouseEvent (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, enumT, intT, objT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (e_Type)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPointF (c_QPointF)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (
+  bs_KeyboardModifiers,
+  bs_MouseButtons,
+  bs_MouseEventFlags,
+  e_MouseButton,
+  e_MouseEventSource,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Gui.QInputEvent (c_QInputEvent)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QMouseEvent"]
+  [ QtExportEvent c_QMouseEvent
+  ]
+
+c_QMouseEvent =
+  addReqIncludes [includeStd "QMouseEvent"] $
+  makeClass (ident "QMouseEvent") Nothing [c_QInputEvent]
+  (collect
+   [ test (qtVersion < [5, 0]) $ mkCtor "new"
+     [enumT e_Type, objT c_QPoint, enumT e_MouseButton, bitspaceT bs_MouseButtons,
+      bitspaceT bs_KeyboardModifiers]
+   , test (qtVersion < [5, 0]) $ mkCtor "newWithGlobalPosition"
+     [enumT e_Type, objT c_QPoint, objT c_QPoint, enumT e_MouseButton, bitspaceT bs_MouseButtons,
+      bitspaceT bs_KeyboardModifiers]
+
+   , test (qtVersion >= [5, 0]) $ mkCtor "new"
+     [enumT e_Type, objT c_QPointF, enumT e_MouseButton, bitspaceT bs_MouseButtons,
+      bitspaceT bs_KeyboardModifiers]
+   , test (qtVersion >= [5, 0]) $ mkCtor "newWithScreenPosition"
+     [enumT e_Type, objT c_QPointF, objT c_QPointF, enumT e_MouseButton, bitspaceT bs_MouseButtons,
+      bitspaceT bs_KeyboardModifiers]
+   , test (qtVersion >= [5, 0]) $ mkCtor "newWithWindowAndScreenPosition"
+     [enumT e_Type, objT c_QPointF, objT c_QPointF, objT c_QPointF, enumT e_MouseButton,
+      bitspaceT bs_MouseButtons, bitspaceT bs_KeyboardModifiers]
+   ]) $
+  collect
+  [ just $ mkConstMethod "button" [] $ enumT e_MouseButton
+  , just $ mkConstMethod "buttons" [] $ bitspaceT bs_MouseButtons
+  , test (qtVersion >= [5, 3]) $ mkConstMethod "flags" [] $ bitspaceT bs_MouseEventFlags
+  , just $ mkConstMethod "globalPos" [] $ objT c_QPoint
+  , just $ mkConstMethod "globalX" [] intT
+  , just $ mkConstMethod "globalY" [] intT
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "localPos" [] $ objT c_QPointF
+  , just $ mkConstMethod "pos" [] $ objT c_QPoint
+  , test (qtVersion < [5, 0]) $ mkConstMethod "posF" [] $ objT c_QPointF
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "screenPos" [] $ objT c_QPointF
+  , test (qtVersion >= [5, 3]) $ mkConstMethod "source" [] $ enumT e_MouseEventSource
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "windowPos" [] $ objT c_QPointF
+  , just $ mkConstMethod "x" [] intT
+  , just $ mkConstMethod "y" [] intT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QPolygon.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QPolygon.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QPolygon.hs
@@ -0,0 +1,84 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QPolygon (
+  aModule,
+  c_QPolygon,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  classSetConversionToGc,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, intT, objT, refT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Interface.Core.QVector (c_QVectorQPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_FillRule)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QPolygon"]
+  [ QtExport $ ExportClass c_QPolygon ]
+
+c_QPolygon =
+  addReqIncludes [includeStd "QPolygon"] $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  classSetConversionToGc $
+  makeClass (ident "QPolygon") Nothing [c_QVectorQPoint]
+  [ mkCtor "new" []
+  , mkCtor "newWithSize" [intT]
+  , mkCtor "newWithPoints" [objT c_QVectorQPoint]
+  , mkCtor "newWithRectangle" [objT c_QRect, boolT]
+  ] $
+  collect
+  [ just $ mkConstMethod "boundingRect" [] $ objT c_QRect
+  , test (qtVersion >= [4, 3]) $ mkConstMethod "containsPoint"
+    [objT c_QPoint, enumT e_FillRule] boolT
+  , test (qtVersion >= [4, 3]) $ mkConstMethod "intersected" [objT c_QPolygon] $ objT c_QPolygon
+  , just $ mkConstMethod "point" [intT] $ objT c_QPoint
+  , just $ mkMethod "putPoints" [intT, intT, objT c_QPolygon, intT] voidT
+  , just $ mkMethod "setPoint" [intT, objT c_QPoint] voidT
+    -- OMIT setPoints
+  , test (qtVersion >= [4, 3]) $ mkConstMethod "subtracted" [objT c_QPolygon] $ objT c_QPolygon
+  , test (qtVersion >= [4, 8]) $ mkMethod "swap" [refT $ objT c_QPolygon] voidT
+  , just $ mkMethod' "translate" "translateByRaw" [intT, intT] voidT
+  , just $ mkMethod' "translate" "translateByPoint" [objT c_QPoint] voidT
+  , test (qtVersion >= [4, 6]) $ mkConstMethod' "translated" "translatedByRaw"
+    [intT, intT] $ objT c_QPolygon
+  , test (qtVersion >= [4, 6]) $ mkConstMethod' "translated" "translatedByPoint"
+    [objT c_QPoint] $ objT c_QPolygon
+  , test (qtVersion >= [4, 3]) $ mkConstMethod "united" [objT c_QPolygon] $ objT c_QPolygon
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QPolygonF.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QPolygonF.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QPolygonF.hs
@@ -0,0 +1,84 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QPolygonF (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  classSetConversionToGc,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, intT, objT, refT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPointF (c_QPointF)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRectF (c_QRectF)
+import Graphics.UI.Qtah.Generator.Interface.Core.QVector (c_QVectorQPointF)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_FillRule)
+import Graphics.UI.Qtah.Generator.Interface.Gui.QPolygon (c_QPolygon)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QPolygonF"]
+  [ QtExport $ ExportClass c_QPolygonF ]
+
+c_QPolygonF =
+  addReqIncludes [includeStd "QPolygonF"] $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  classSetConversionToGc $
+  makeClass (ident "QPolygonF") Nothing [c_QVectorQPointF]
+  [ mkCtor "new" []
+  , mkCtor "newWithSize" [intT]
+  , mkCtor "newWithPoints" [objT c_QVectorQPointF]
+  , mkCtor "newWithPolygon" [objT c_QPolygon]
+  , mkCtor "newWithRectangle" [objT c_QRectF]
+  ] $
+  collect
+  [ just $ mkConstMethod "boundingRect" [] $ objT c_QRectF
+  , test (qtVersion >= [4, 3]) $ mkConstMethod "containsPoint"
+    [objT c_QPointF, enumT e_FillRule] boolT
+  , test (qtVersion >= [4, 3]) $ mkConstMethod "intersected" [objT c_QPolygonF] $ objT c_QPolygonF
+  , just $ mkConstMethod "isClosed" [] boolT
+  , test (qtVersion >= [4, 3]) $ mkConstMethod "subtracted" [objT c_QPolygonF] $ objT c_QPolygonF
+  , test (qtVersion >= [4, 8]) $ mkMethod "swap" [refT $ objT c_QPolygonF] voidT
+  , just $ mkConstMethod "toPolygon" [] $ objT c_QPolygon
+  , just $ mkMethod' "translate" "translateByRaw" [intT, intT] voidT
+  , just $ mkMethod' "translate" "translateByPoint" [objT c_QPointF] voidT
+  , test (qtVersion >= [4, 6]) $ mkConstMethod' "translated" "translatedByRaw"
+    [intT, intT] $ objT c_QPolygonF
+  , test (qtVersion >= [4, 6]) $ mkConstMethod' "translated" "translatedByPoint"
+    [objT c_QPointF] $ objT c_QPolygonF
+  , test (qtVersion >= [4, 3]) $ mkConstMethod "united"
+    [objT c_QPolygonF] $ objT c_QPolygonF
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QRegion.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QRegion.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QRegion.hs
@@ -0,0 +1,104 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QRegion (
+  aModule,
+  c_QRegion,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass, ExportEnum),
+  addReqIncludes,
+  classSetConversionToGc,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  )
+import Foreign.Hoppy.Generator.Spec.ClassFeature (
+  ClassFeature (Assignable, Copyable, Equatable),
+  classAddFeatures,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, intT, objT, refT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QRegion"]
+  [ QtExport $ ExportClass c_QRegion
+  , QtExport $ ExportEnum e_RegionType
+  ]
+
+c_QRegion =
+  addReqIncludes [includeStd "QRegion"] $
+  classAddFeatures [Assignable, Copyable, Equatable] $
+  classSetConversionToGc $
+  makeClass (ident "QRegion") Nothing []
+  [ mkCtor "new" []
+  , mkCtor "newFromPoints" [intT, intT, intT, intT, enumT e_RegionType]
+    -- TODO newFromPolygon (needs QPolygon)
+    -- TODO newFromBitmap (needs QBitmap)
+  , mkCtor "newFromRect" [objT c_QRect, enumT e_RegionType]
+  ] $
+  collect
+  [ just $ mkConstMethod "boundingRect" [] $ objT c_QRect
+  , just $ mkConstMethod' "contains" "containsPoint" [objT c_QPoint] boolT
+  , just $ mkConstMethod' "contains" "containsRect" [objT c_QRect] boolT
+  , test (qtVersion >= [4, 2]) $
+    mkConstMethod' "intersected" "intersected" [objT c_QRegion] $ objT c_QRegion
+  , test (qtVersion >= [4, 4]) $
+    mkConstMethod' "intersected" "intersectedWithRect" [objT c_QRect] $ objT c_QRegion
+  , test (qtVersion >= [4, 2]) $ mkConstMethod' "intersects" "intersects" [objT c_QRegion] boolT
+  , test (qtVersion >= [4, 2]) $ mkConstMethod' "intersects" "intersectsRect" [objT c_QRect] boolT
+  , just $ mkConstMethod "isEmpty" [] boolT
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "isNull" [] boolT
+  , test (qtVersion >= [4, 6]) $ mkConstMethod "rectCount" [] intT
+    -- TODO rects
+    -- TODO setRects
+  , test (qtVersion >= [4, 2]) $
+    mkConstMethod "subtracted" [objT c_QRegion] $ objT c_QRegion
+  , test (qtVersion >= [4, 8]) $ mkMethod "swap" [refT $ objT c_QRegion] voidT
+  , just $ mkMethod' "translate" "translateByCoords" [intT, intT] voidT
+  , just $ mkMethod' "translate" "translateByPoint" [objT c_QPoint] voidT
+  , test (qtVersion >= [4, 1]) $
+    mkConstMethod' "translated" "translatedByCoords" [intT, intT] $ objT c_QRegion
+  , test (qtVersion >= [4, 1]) $
+    mkConstMethod' "translated" "translatedByPoint" [objT c_QPoint] $ objT c_QRegion
+  , test (qtVersion >= [4, 2]) $
+    mkConstMethod' "united" "united" [objT c_QRegion] $ objT c_QRegion
+  , test (qtVersion >= [4, 4]) $
+    mkConstMethod' "united" "unitedWithRect" [objT c_QRect] $ objT c_QRegion
+  , test (qtVersion >= [4, 2]) $
+    mkConstMethod' "xored" "xored" [objT c_QRegion] $ objT c_QRegion
+  ]
+
+e_RegionType =
+  makeQtEnum (ident1 "QRegion" "RegionType") [includeStd "QRegion"]
+  [ (0, ["rectangle"])
+  , (1, ["ellipse"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QShowEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QShowEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QShowEvent.hs
@@ -0,0 +1,46 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QShowEvent (
+  aModule,
+  c_QShowEvent,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkCtor,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Core.QEvent (c_QEvent)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QShowEvent"]
+  [ QtExportEvent c_QShowEvent
+  ]
+
+c_QShowEvent =
+  addReqIncludes [includeStd "QShowEvent"] $
+  makeClass (ident "QShowEvent") Nothing [c_QEvent]
+  [ mkCtor "new" []
+  ]
+  []
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QValidator.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QValidator.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QValidator.hs
@@ -0,0 +1,66 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QValidator (
+  aModule,
+  c_QValidator,
+  e_State,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  )
+import Foreign.Hoppy.Generator.Types (enumT, intT, objT, refT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_Listener)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QValidator"] $
+  (QtExport $ ExportClass c_QValidator) :
+  map QtExportSignal signals ++
+  [ QtExport $ ExportEnum e_State ]
+
+c_QValidator =
+  addReqIncludes [includeStd "QValidator"] $
+  makeClass (ident "QValidator") Nothing [c_QObject] [] $
+  [ mkConstMethod "fixup" [refT $ objT c_QString] voidT
+    -- TODO locale
+    -- TODO setLocale
+  , mkConstMethod "validate" [refT $ objT c_QString, refT intT] $ enumT e_State
+  ]
+
+signals =
+  [ makeSignal c_QValidator "changed" c_Listener
+  ]
+
+e_State =
+  makeQtEnum (ident1 "QValidator" "State") [includeStd "QValidator"]
+  [ (0, ["invalid"])
+  , (1, ["intermediate"])
+  , (2, ["acceptable"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Gui/QWheelEvent.hs b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QWheelEvent.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Gui/QWheelEvent.hs
@@ -0,0 +1,84 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Gui.QWheelEvent (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, enumT, intT, objT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPointF (c_QPointF)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (
+  bs_KeyboardModifiers,
+  bs_MouseButtons,
+  e_Orientation,
+  e_ScrollPhase,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Gui.QInputEvent (c_QInputEvent)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Gui", "QWheelEvent"]
+  [ QtExportEvent c_QWheelEvent
+  ]
+
+c_QWheelEvent =
+  addReqIncludes [includeStd "QWheelEvent"] $
+  makeClass (ident "QWheelEvent") Nothing [c_QInputEvent]
+  (collect
+   [ test (qtVersion < [5, 0]) $ mkCtor "new"
+     [objT c_QPoint, intT, bitspaceT bs_MouseButtons, bitspaceT bs_KeyboardModifiers,
+      enumT e_Orientation]
+   , test (qtVersion < [5, 0]) $ mkCtor "newWithGlobalPosition"
+     [objT c_QPoint, objT c_QPoint, intT, bitspaceT bs_MouseButtons, bitspaceT bs_KeyboardModifiers,
+      enumT e_Orientation]
+
+   , test (qtVersion >= [5, 0]) $ mkCtor "new"
+     [objT c_QPointF, objT c_QPointF, objT c_QPoint, objT c_QPoint, intT, enumT e_Orientation,
+      bitspaceT bs_MouseButtons, bitspaceT bs_KeyboardModifiers]
+   , test (qtVersion >= [5, 2]) $ mkCtor "newWithPhase"
+     [objT c_QPointF, objT c_QPointF, objT c_QPoint, objT c_QPoint, intT, enumT e_Orientation,
+      bitspaceT bs_MouseButtons, bitspaceT bs_KeyboardModifiers, enumT e_ScrollPhase]
+   ]) $
+  collect
+  [ test (qtVersion >= [5, 0]) $ mkConstMethod "angleDelta" [] $ objT c_QPoint
+  , just $ mkConstMethod "buttons" [] $ bitspaceT bs_MouseButtons
+  , test (qtVersion < [5, 0]) $ mkConstMethod "delta" [] intT
+  , just $ mkConstMethod "globalPos" [] $ objT c_QPoint
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "globalPosF" [] $ objT c_QPointF
+  , just $ mkConstMethod "globalX" [] intT
+  , just $ mkConstMethod "globalY" [] intT
+  , test (qtVersion >= [5, 2]) $ mkConstMethod "phase" [] $ enumT e_ScrollPhase
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "pixelDelta" [] $ objT c_QPoint
+  , just $ mkConstMethod "pos" [] $ objT c_QPoint
+  , test (qtVersion >= [5, 0]) $ mkConstMethod "posF" [] $ objT c_QPointF
+  , just $ mkConstMethod "x" [] intT
+  , just $ mkConstMethod "y" [] intT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Imports.hs b/src/Graphics/UI/Qtah/Generator/Interface/Imports.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Imports.hs
@@ -0,0 +1,52 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+-- | Shared bindings for @\"Qtah*\"@ qualified imports in generated bindings.
+-- Some classes use qualified imports that don't start with @\"Qtah\"@; such
+-- imports are one-off and are not listed here.
+module Graphics.UI.Qtah.Generator.Interface.Imports (
+  importForChar,
+  importForEvent,
+  importForForeign,
+  importForForeignC,
+  importForPrelude,
+  importForSignal,
+  importForRuntime,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (HsImportSet, hsQualifiedImport)
+
+importForChar :: HsImportSet
+importForChar = hsQualifiedImport "Data.Char" "QtahDC"
+
+importForEvent :: HsImportSet
+importForEvent = hsQualifiedImport "Graphics.UI.Qtah.Event" "QtahEvent"
+
+importForForeign :: HsImportSet
+importForForeign = hsQualifiedImport "Foreign" "QtahF"
+
+importForForeignC :: HsImportSet
+importForForeignC = hsQualifiedImport "Foreign.C" "QtahFC"
+
+importForPrelude :: HsImportSet
+importForPrelude = hsQualifiedImport "Prelude" "QtahP"
+
+importForSignal :: HsImportSet
+importForSignal = hsQualifiedImport "Graphics.UI.Qtah.Signal" "QtahSignal"
+
+importForRuntime :: HsImportSet
+importForRuntime = hsQualifiedImport "Foreign.Hoppy.Runtime" "QtahFHR"
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Listener.hs b/src/Graphics/UI/Qtah/Generator/Interface/Listener.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Listener.hs
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets.hs
@@ -0,0 +1,114 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets (modules) where
+
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton as QAbstractButton
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractScrollArea as QAbstractScrollArea
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSlider as QAbstractSlider
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSpinBox as QAbstractSpinBox
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QAction as QAction
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QActionGroup as QActionGroup
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QApplication as QApplication
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QBoxLayout as QBoxLayout
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QButtonGroup as QButtonGroup
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QCheckBox as QCheckBox
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QDial as QDial
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QDialog as QDialog
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QDialogButtonBox as QDialogButtonBox
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QDoubleSpinBox as QDoubleSpinBox
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QFileDialog as QFileDialog
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QFormLayout as QFormLayout
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QFrame as QFrame
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QGridLayout as QGridLayout
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QGroupBox as QGroupBox
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QHBoxLayout as QHBoxLayout
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QLabel as QLabel
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QLayout as QLayout
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QLayoutItem as QLayoutItem
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QLineEdit as QLineEdit
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QMainWindow as QMainWindow
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QMenu as QMenu
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QMenuBar as QMenuBar
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QMessageBox as QMessageBox
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QProgressBar as QProgressBar
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QPushButton as QPushButton
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QRadioButton as QRadioButton
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QRubberBand as QRubberBand
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QScrollArea as QScrollArea
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QScrollBar as QScrollBar
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QSlider as QSlider
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QSpinBox as QSpinBox
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QSplitter as QSplitter
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QStackedLayout as QStackedLayout
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QStackedWidget as QStackedWidget
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QStatusBar as QStatusBar
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QTabWidget as QTabWidget
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QTextEdit as QTextEdit
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QVBoxLayout as QVBoxLayout
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget as QWidget
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+modules :: [AModule]
+modules =
+  [ QAbstractButton.aModule
+  , QAbstractScrollArea.aModule
+  , QAbstractSlider.aModule
+  , QAbstractSpinBox.aModule
+  , QAction.aModule
+  , QActionGroup.aModule
+  , QApplication.aModule
+  , QBoxLayout.aModule
+  , QButtonGroup.aModule
+  , QCheckBox.aModule
+  , QDial.aModule
+  , QDialog.aModule
+  , QDialogButtonBox.aModule
+  , QDoubleSpinBox.aModule
+  , QFileDialog.aModule
+  , QFormLayout.aModule
+  , QFrame.aModule
+  , QGridLayout.aModule
+  , QGroupBox.aModule
+  , QHBoxLayout.aModule
+  , QLabel.aModule
+  , QLayout.aModule
+  , QLayoutItem.aModule
+  , QLineEdit.aModule
+  , QMainWindow.aModule
+  , QMenu.aModule
+  , QMenuBar.aModule
+  , QMessageBox.aModule
+  , QProgressBar.aModule
+  , QPushButton.aModule
+  , QRadioButton.aModule
+  , QRubberBand.aModule
+  , QScrollArea.aModule
+  , QScrollBar.aModule
+  , QSlider.aModule
+  , QSpinBox.aModule
+  , QSplitter.aModule
+  , QStackedLayout.aModule
+  , QStackedWidget.aModule
+  , QStatusBar.aModule
+  , QTabWidget.aModule
+  , QTextEdit.aModule
+  , QVBoxLayout.aModule
+  , QWidget.aModule
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractButton.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractButton.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractButton.hs
@@ -0,0 +1,78 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton (
+  aModule,
+  c_QAbstractButton,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, intT, objT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_Listener, c_ListenerBool)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QAbstractButton"] $
+  QtExport (ExportClass c_QAbstractButton) :
+  map QtExportSignal signals
+
+c_QAbstractButton =
+  addReqIncludes [includeStd "QAbstractButton"] $
+  makeClass (ident "QAbstractButton") Nothing
+  [ c_QWidget ]
+  [] $  -- Abstact.
+  [ mkMethod "animateClick" [intT] voidT
+  , mkMethod "click" [] voidT
+    -- TODO group
+  , mkMethod "toggle" [] voidT
+  ] ++
+  mkProps
+  [ mkProp "autoExclusive" boolT
+  , mkProp "autoRepeat" boolT
+  , mkProp "autoRepeatDelay" intT
+  , mkProp "autoRepeatInterval" intT
+  , mkBoolIsProp "checkable"
+  , mkBoolIsProp "checked"
+  , mkBoolIsProp "down"
+    -- TODO icon
+  , mkProp "iconSize" $ objT c_QSize
+    -- TODO shortcut
+  , mkProp "text" $ objT c_QString
+  ]
+
+signals =
+  [ makeSignal c_QAbstractButton "clicked" c_ListenerBool
+  , makeSignal c_QAbstractButton "pressed" c_Listener
+  , makeSignal c_QAbstractButton "released" c_Listener
+  , makeSignal c_QAbstractButton "toggled" c_ListenerBool
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractButton.hs-boot b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractButton.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractButton.hs-boot
@@ -0,0 +1,24 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton (
+  c_QAbstractButton,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (Class)
+
+c_QAbstractButton :: Class
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractScrollArea.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractScrollArea.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractScrollArea.hs
@@ -0,0 +1,65 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractScrollArea (
+  aModule,
+  c_QAbstractScrollArea,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, enumT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment, e_ScrollBarPolicy)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QAbstractScrollArea"]
+  [ QtExport $ ExportClass c_QAbstractScrollArea ]
+
+c_QAbstractScrollArea =
+  addReqIncludes [includeStd "QAbstractScrollArea"] $
+  makeClass (ident "QAbstractScrollArea") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  [ mkMethod "addScrollBarWidget" [ptrT $ objT c_QWidget, bitspaceT bs_Alignment] voidT
+  , mkConstMethod "maximumViewportSize" [] $ objT c_QSize
+    -- TODO scrollBarWidgets
+  ] ++
+  mkProps
+  [ mkProp "cornerWidget" $ ptrT $ objT c_QWidget
+    -- TODO horizontalScrollBar
+  , mkProp "horizontalScrollBarPolicy" $ enumT e_ScrollBarPolicy
+    -- TODO verticalScrollBar
+  , mkProp "verticalScrollBarPolicy" $ enumT e_ScrollBarPolicy
+  , mkProp "viewport" $ ptrT $ objT c_QWidget
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractSlider.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractSlider.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractSlider.hs
@@ -0,0 +1,105 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSlider (
+  aModule,
+  c_QAbstractSlider,
+  e_SliderAction,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass, ExportEnum),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  makeEnum,
+  mkBoolIsProp,
+  mkBoolHasProp,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  toExtName,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_Orientation)
+import Graphics.UI.Qtah.Generator.Interface.Listener (
+  c_Listener,
+  c_ListenerInt,
+  c_ListenerIntInt,
+  c_ListenerQAbstractSliderAction,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QAbstractSlider"] $
+  QtExport (ExportClass c_QAbstractSlider) :
+  map QtExportSignal signals ++
+  [ QtExport $ ExportEnum e_SliderAction ]
+
+c_QAbstractSlider =
+  addReqIncludes [includeStd "QAbstractSlider"] $
+  makeClass (ident "QAbstractSlider") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  [ mkMethod "triggerAction" [enumT e_SliderAction] voidT
+  ] ++
+  mkProps
+  [ mkProp "invertedAppearance" boolT
+  , mkProp "invertedControls" boolT
+  , mkProp "maximum" intT
+  , mkProp "minimum" intT
+  , mkProp "orientation" $ enumT e_Orientation
+  , mkProp "pageStep" intT
+  , mkProp "singleStep" intT
+  , mkBoolIsProp "sliderDown"
+  , mkProp "sliderPosition" intT
+  , mkBoolHasProp "tracking"
+  , mkProp "value" intT
+  ]
+
+signals =
+  [ makeSignal c_QAbstractSlider "actionTriggered" c_ListenerQAbstractSliderAction
+  , makeSignal c_QAbstractSlider "rangeChanged" c_ListenerIntInt
+  , makeSignal c_QAbstractSlider "sliderMoved" c_ListenerInt
+  , makeSignal c_QAbstractSlider "sliderPressed" c_Listener
+  , makeSignal c_QAbstractSlider "sliderReleased" c_Listener
+  , makeSignal c_QAbstractSlider "valueChanged" c_ListenerInt
+  ]
+
+-- This uses 'makeEnum' rather than 'makeQtEnum' and also drops a "Slider"
+-- prefix off of the start of each value name, unlike most Qt enums, because
+-- 'QAbstractSliderSliderAction_SliderNoAction' is a tad too repetetive.
+e_SliderAction =
+  addReqIncludes [includeStd "QAbstractSlider"] $
+  makeEnum (ident1 "QAbstractSlider" "SliderAction") (Just $ toExtName "QAbstractSliderAction")
+  [ (0, ["no", "action"])
+  , (1, ["single", "step", "add"])
+  , (2, ["single", "step", "sub"])
+  , (3, ["page", "step", "add"])
+  , (4, ["page", "step", "sub"])
+  , (5, ["to", "minimum"])
+  , (6, ["to", "maximum"])
+  , (7, ["move"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractSlider.hs-boot b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractSlider.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractSlider.hs-boot
@@ -0,0 +1,24 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSlider (
+  e_SliderAction,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (CppEnum)
+
+e_SliderAction :: CppEnum
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractSpinBox.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractSpinBox.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAbstractSpinBox.hs
@@ -0,0 +1,120 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSpinBox (
+  aModule,
+  c_QAbstractSpinBox,
+  e_ButtonSymbols,
+  e_CorrectionMode,
+  e_StepEnabledFlag,
+  bs_StepEnabled,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportBitspace, ExportClass, ExportEnum),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkBoolHasProp,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, enumT, intT, objT, ptrT, refT, voidT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_Listener)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QAbstractSpinBox"] $
+  QtExport (ExportClass c_QAbstractSpinBox) :
+  map QtExportSignal signals ++
+  (map QtExport . collect)
+  [ test (qtVersion >= [4, 2]) $ ExportEnum e_ButtonSymbols
+  , just $ ExportEnum e_CorrectionMode
+  , just $ ExportEnum e_StepEnabledFlag
+  , just $ ExportBitspace bs_StepEnabled
+  ]
+
+c_QAbstractSpinBox =
+  addReqIncludes [includeStd "QAbstractSpinBox"] $
+  makeClass (ident "QAbstractSpinBox") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  collect
+  [ just $ mkMethod "clear" [] voidT
+  , test (qtVersion >= [4, 2]) $ mkConstMethod "hasAcceptableInput" [] boolT
+  , just $ mkConstMethod "fixup" [refT $ objT c_QString] voidT
+  , just $ mkMethod "interpretText" [] voidT
+  , just $ mkMethod "selectAll" [] voidT
+  , just $ mkMethod "stepBy" [intT] voidT
+  , just $ mkMethod "stepDown" [] voidT
+  , just $ mkMethod "stepUp" [] voidT
+  , just $ mkConstMethod "text" [] $ objT c_QString
+    -- TODO validate
+  ] ++
+  (mkProps . collect)
+  [ test (qtVersion >= [4, 2]) $ mkBoolIsProp "accelerated"
+  , just $ mkProp "alignment" $ bitspaceT bs_Alignment
+  , test (qtVersion >= [4, 2]) $ mkProp "buttonSymbols" $ enumT e_ButtonSymbols
+  , just $ mkProp "correctionMode" $ enumT e_CorrectionMode
+  , test (qtVersion >= [4, 3]) $ mkBoolHasProp "frame"
+  , just $ mkProp "keyboardTracking" boolT
+  , just $ mkBoolIsProp "readOnly"
+  , test (qtVersion >= [5, 3]) $ mkBoolIsProp "groupSeparatorShown"
+  , just $ mkProp "specialValueText" $ objT c_QString
+  , just $ mkProp "wrapping" boolT
+  ]
+
+signals =
+  [ makeSignal c_QAbstractSpinBox "editingFinished" c_Listener
+  ]
+
+e_ButtonSymbols =
+  addReqIncludes [includeStd "QAbstractSpinBox"] $
+  makeQtEnum (ident1 "QAbstractSpinBox" "ButtonSymbols") [includeStd "QAbstractSpinBox"]
+  [ (0, ["up", "down", "arrows"])
+  , (1, ["plus", "minus"])
+  , (2, ["no", "buttons"])
+  ]
+
+e_CorrectionMode =
+  makeQtEnum (ident1 "QAbstractSpinBox" "CorrectionMode") [includeStd "QAbstractSpinBox"]
+  [ (0, ["correct", "to", "previous", "value"])
+  , (1, ["correct", "to", "nearest", "value"])
+  ]
+
+(e_StepEnabledFlag, bs_StepEnabled) =
+  makeQtEnumBitspace (ident1 "QAbstractSpinBox" "StepEnabledFlag") "StepEnabled"
+  [includeStd "QAbstractSpinBox"]
+  [ (0x0, ["step", "none"])
+  , (0x1, ["step", "up", "enabled"])
+  , (0x2, ["step", "down", "enabled"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAction.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAction.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAction.hs
@@ -0,0 +1,146 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QAction (
+  aModule,
+  c_QAction,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_Listener, c_ListenerBool)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QActionGroup (c_QActionGroup)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QMenu (c_QMenu)
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QAction"] $
+  QtExport (ExportClass c_QAction) :
+  map QtExportSignal signals ++
+  (map (QtExport . ExportEnum) . collect)
+  [ just $ e_ActionEvent
+  , just $ e_MenuRole
+  , just $ e_Priority
+  , test (qtVersion < [5]) $ e_SoftKeyRole
+  ]
+
+c_QAction =
+  addReqIncludes [includeStd "QAction"] $
+  makeClass (ident "QAction") Nothing
+  [ c_QObject ]
+  [ mkCtor "new" [ptrT $ objT c_QObject]
+  , mkCtor "newWithText" [objT c_QString, ptrT $ objT c_QObject]
+    -- TODO newWithIconAndText
+  ] $
+  [ mkMethod "activate" [enumT e_ActionEvent] voidT
+    -- TODO associatedGraphicsWidgets
+    -- TODO associatedWidgets
+  , mkMethod "hover" [] voidT
+  , mkConstMethod "parentWidget" [] $ ptrT $ objT c_QWidget
+  , mkConstMethod "priority" [] $ enumT e_Priority
+  , mkMethod "setDisabled" [boolT] voidT
+  , mkMethod "setPriority" [enumT e_Priority] voidT
+    -- TODO setShortcuts
+    -- TODO shortcuts
+  , mkMethod "showStatusText" [ptrT $ objT c_QWidget] boolT
+  , mkMethod "toggle" [] voidT
+  , mkMethod "trigger" [] voidT
+  ] ++
+  (mkProps . collect)
+  [ just $ mkProp "actionGroup" $ ptrT $ objT c_QActionGroup
+  , just $ mkProp "autoRepeat" boolT
+  , just $ mkBoolIsProp "checkable"
+  , just $ mkBoolIsProp "checked"
+    -- TODO data
+  , just $ mkBoolIsProp "enabled"
+    -- TODO font
+    -- TODO icon
+  , just $ mkProp "iconText" $ objT c_QString
+  , just $ mkBoolIsProp "iconVisibleInMenu"
+  , just $ mkProp "menu" $ ptrT $ objT c_QMenu
+  , just $ mkProp "menuRole" $ enumT e_MenuRole
+  , just $ mkBoolIsProp "separator"
+    -- TODO shortcut
+    -- TODO shortcutContext
+  , test (qtVersion < [5]) $ mkProp "softKeyRole" $ enumT e_SoftKeyRole
+  , just $ mkProp "statusTip" $ objT c_QString
+  , just $ mkProp "text" $ objT c_QString
+  , just $ mkProp "toolTip" $ objT c_QString
+  , just $ mkBoolIsProp "visible"
+  , just $ mkProp "whatsThis" $ objT c_QString
+  ]
+
+signals =
+  [ makeSignal c_QAction "changed" c_Listener
+  , makeSignal c_QAction "hovered" c_Listener
+  , makeSignal c_QAction "toggled" c_ListenerBool
+  , makeSignal c_QAction "triggered" c_ListenerBool
+  ]
+
+e_ActionEvent =
+  makeQtEnum (ident1 "QAction" "ActionEvent") [includeStd "QAction"]
+  [ (0, ["trigger"])
+  , (1, ["hover"])
+  ]
+
+e_MenuRole =
+  makeQtEnum (ident1 "QAction" "MenuRole") [includeStd "QAction"]
+  [ (0, ["no", "role"])
+  , (1, ["text", "heuristic", "role"])
+  , (2, ["application", "specific", "role"])
+  , (3, ["about", "qt", "role"])
+  , (4, ["about", "role"])
+  , (5, ["preferences", "role"])
+  , (6, ["quit", "role"])
+  ]
+
+e_Priority =
+  makeQtEnum (ident1 "QAction" "Priority") [includeStd "QAction"]
+  [ (0, ["low", "priority"])
+  , (128, ["normal", "priority"])
+  , (256, ["high", "priority"])
+  ]
+
+-- | Removed in Qt 5.
+e_SoftKeyRole =
+  makeQtEnum (ident1 "QAction" "SoftKeyRole") [includeStd "QAction"]
+  [ (0, ["no", "soft", "key"])
+  , (1, ["positive", "soft", "key"])
+  , (2, ["negative", "soft", "key"])
+  , (3, ["select", "soft", "key"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAction.hs-boot b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAction.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QAction.hs-boot
@@ -0,0 +1,24 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QAction (
+  c_QAction,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (Class)
+
+c_QAction :: Class
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QActionGroup.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QActionGroup.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QActionGroup.hs
@@ -0,0 +1,74 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QActionGroup (
+  aModule,
+  c_QActionGroup,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerPtrQAction)
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Widgets.QAction (c_QAction)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QActionGroup"] $
+  QtExport (ExportClass c_QActionGroup) :
+  map QtExportSignal signals
+
+c_QActionGroup =
+  addReqIncludes [includeStd "QActionGroup"] $
+  makeClass (ident "QActionGroup") Nothing
+  [ c_QObject ]
+  [ mkCtor "new" [ptrT $ objT c_QObject]
+  ] $
+  [ -- TODO actions
+    mkMethod' "addAction" "addAction" [ptrT $ objT c_QAction] $ ptrT $ objT c_QAction
+  , mkMethod' "addAction" "addNewAction" [objT c_QString] $ ptrT $ objT c_QAction
+    -- TODO addNewActionWithIcon
+  , mkConstMethod "checkedAction" [] $ ptrT $ objT c_QAction
+  , mkMethod "removeAction" [ptrT $ objT c_QAction] voidT
+  , mkMethod "setDisabled" [boolT] voidT
+  ] ++
+  mkProps
+  [ mkBoolIsProp "enabled"
+  , mkBoolIsProp "exclusive"
+  , mkBoolIsProp "visible"
+  ]
+
+signals =
+  [ makeSignal c_QActionGroup "hovered" c_ListenerPtrQAction
+  , makeSignal c_QActionGroup "triggered" c_ListenerPtrQAction
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QApplication.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QApplication.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QApplication.hs
@@ -0,0 +1,171 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QApplication (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  MethodApplicability (MStatic),
+  Purity (Nonpure),
+  addReqIncludes,
+  ident,
+  ident1,
+  ident2,
+  includeLocal,
+  includeStd,
+  makeFnMethod,
+  makeClass,
+  mkConstMethod,
+  mkProp,
+  mkProps,
+  mkStaticMethod,
+  mkStaticMethod',
+  mkStaticProp,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (keypadNavigation, qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QCoreApplication (c_QCoreApplication)
+import Graphics.UI.Qtah.Generator.Interface.Core.QList (c_QListQWidget)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.QStringList (c_QStringList)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_LayoutDirection, e_NavigationMode)
+import Graphics.UI.Qtah.Generator.Interface.Gui.QClipboard (c_QClipboard)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_Listener, c_ListenerPtrQWidgetPtrQWidget)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QApplication"] $
+  [ QtExport $ ExportClass c_QApplication
+  ] ++ map QtExportSignal signals ++
+  collect
+  [ test (qtVersion < [5]) $ QtExport $ ExportEnum e_Type
+  ]
+
+c_QApplication =
+  addReqIncludes [ includeStd "QApplication"
+                 , includeLocal "wrap_qapplication.hpp"
+                 ] $
+  makeClass (ident "QApplication") Nothing [c_QCoreApplication] [] $
+  collect
+  [ just $ makeFnMethod (ident2 "qtah" "qapplication" "create") "new" MStatic Nonpure
+    [objT c_QStringList] $ ptrT $ objT c_QApplication
+  , just $ mkStaticMethod "aboutQt" [] voidT
+  , just $ mkStaticMethod "activeModalWidget" [] $ ptrT $ objT c_QWidget
+  , just $ mkStaticMethod "activePopupWidget" [] $ ptrT $ objT c_QWidget
+  , just $ mkStaticMethod "alert" [ptrT $ objT c_QWidget, intT] voidT
+  , just $ mkStaticMethod "allWidgets" [] $ objT c_QListQWidget
+  , just $ mkStaticMethod "beep" [] voidT
+    -- TODO changeOverrideCursor
+  , just $ mkStaticMethod "clipboard" [] $ ptrT $ objT c_QClipboard
+  , just $ mkStaticMethod "closeAllWindows" [] voidT
+    -- TODO commitData
+    -- TODO desktop
+  , just $ mkStaticMethod "focusWidget" [] $ ptrT $ objT c_QWidget
+    -- TODO font
+    -- TODO fontMetrics
+    -- TODO inputContext
+    -- TODO isEffectEnabled
+  , just $ mkStaticMethod "isLeftToRight" [] boolT
+  , just $ mkStaticMethod "isRightToLeft" [] boolT
+  , just $ mkConstMethod "isSessionRestored" [] boolT
+  , test (qtVersion < [5]) $ mkStaticMethod "keyboardInputDirection" [] $ enumT e_LayoutDirection
+  , just $ mkStaticMethod "keyboardInputInterval" [] intT
+    -- TODO keyboardInputLocale (<5)
+    -- TODO keyboardModifiers
+  , just $ mkStaticMethod "layoutDirection" [] $ enumT e_LayoutDirection
+    -- TODO macEventFilter
+    -- TODO mouseButtons
+  , test keypadNavigation $ mkStaticMethod "navigationMode" [] $ enumT e_NavigationMode
+    -- TODO overrideCursor
+    -- TODO palette
+    -- TODO queryKeyboardModifiers
+  , just $ mkStaticMethod "quitOnLastWindowClosed" [] boolT
+    -- TODO qwsDecoration
+    -- TODO qwsEventFilter
+    -- TODO qwsSetCustomColors
+    -- TODO qwsSetDecoration
+  , just $ mkStaticMethod "restoreOverrideCursor" [] voidT
+    -- TODO saveState
+  , just $ mkConstMethod "sessionId" [] $ objT c_QString
+  , just $ mkConstMethod "sessionKey" [] $ objT c_QString
+    -- TODO setEffectEnabled
+    -- TODO setFont
+    -- TODO setGraphicsSystem (<5)
+    -- TODO setInputContext
+  , just $ mkStaticMethod "setKeyboardInputInterval" [intT] voidT
+  , just $ mkStaticMethod "setLayoutDirection" [enumT e_LayoutDirection] voidT
+  , test keypadNavigation $ mkStaticMethod "setNavigationMode" [enumT e_NavigationMode] voidT
+    -- TODO setOverrideCursor
+    -- TODO setPalette
+  , just $ mkStaticMethod "setQuitOnLastWindowClosed" [boolT] voidT
+    -- TODO setStyle
+    -- TODO style
+  , test (qtVersion < [5]) $ mkStaticMethod "syncX" [] voidT
+    -- TODO symbianEventFilter
+    -- TODO symbianProcessEvent
+  , just $ mkStaticMethod' "topLevelAt" "topLevelAtPoint" [objT c_QPoint] $ ptrT $ objT c_QWidget
+  , just $ mkStaticMethod' "topLevelAt" "topLevelAtRaw" [intT, intT] $ ptrT $ objT c_QWidget
+    -- TODO topLevelWidgets
+    -- We rename type() since @type@ is a Haskell keyword.
+  , test (qtVersion < [5]) $ mkStaticMethod' "type" "applicationType" [] $ enumT e_Type
+  , just $ mkStaticMethod' "widgetAt" "widgetAtPoint" [objT c_QPoint] $ ptrT $ objT c_QWidget
+  , just $ mkStaticMethod' "widgetAt" "widgetAtRaw" [intT, intT] $ ptrT $ objT c_QWidget
+    -- TODO x11EventFilter
+    -- TODO x11ProcessEvent
+  ] ++
+  mkProps
+  [ mkStaticProp "activeWindow" $ ptrT $ objT c_QWidget
+  , mkProp "autoSipEnabled" boolT
+  , mkStaticProp "colorSpec" intT
+  , mkStaticProp "cursorFlashTime" intT
+  , mkStaticProp "desktopSettingsAware" boolT
+  , mkStaticProp "doubleClickInterval" intT
+  , mkStaticProp "globalStrut" $ objT c_QSize
+  , mkProp "startDragDistance" intT
+  , mkProp "startDragTime" intT
+  , mkProp "styleSheet" $ objT c_QString
+  , mkStaticProp "wheelScrollLines" intT
+    -- TODO windowIcon
+  ]
+
+signals =
+  [ makeSignal c_QApplication "aboutToReleaseGpuResources" c_Listener
+  , makeSignal c_QApplication "aboutToUseGpuResources" c_Listener
+    -- TODO commitDataRequest
+  , makeSignal c_QApplication "focusChanged" c_ListenerPtrQWidgetPtrQWidget
+  , makeSignal c_QApplication "fontDatabaseChanged" c_Listener
+  , makeSignal c_QApplication "lastWindowClosed" c_Listener
+    -- TODO quit (static!)
+    -- TODO saveStateRequest
+  ]
+
+-- | Removed in Qt 5.
+e_Type =
+  makeQtEnum (ident1 "QApplication" "Type") [includeStd "QApplication"]
+  [ (0, ["tty"])
+  , (1, ["gui", "client"])
+  , (2, ["gui", "server"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QBoxLayout.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QBoxLayout.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QBoxLayout.hs
@@ -0,0 +1,92 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QBoxLayout (
+  aModule,
+  c_QBoxLayout,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, enumT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QLayout (c_QLayout)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QBoxLayout"]
+  [ QtExport $ ExportClass c_QBoxLayout
+  , QtExport $ ExportEnum e_Direction
+  ]
+
+c_QBoxLayout =
+  addReqIncludes [includeStd "QBoxLayout"] $
+  makeClass (ident "QBoxLayout") Nothing [c_QLayout]
+  [ mkCtor "new" [enumT e_Direction]
+  , mkCtor "newWithParent" [enumT e_Direction, ptrT $ objT c_QWidget]
+  ] $
+  [ mkMethod' "addLayout" "addLayout" [ptrT $ objT c_QLayout] voidT
+  , mkMethod' "addLayout" "addLayoutWithStretch" [ptrT $ objT c_QLayout, intT] voidT
+  , mkMethod "addSpacing" [intT] voidT
+  , mkMethod' "addStretch" "addStretch" [] voidT
+  , mkMethod' "addStretch" "addStretchOf" [intT] voidT
+  , mkMethod "addStrut" [intT] voidT
+  , mkMethod' "addWidget" "addWidget" [ptrT $ objT c_QWidget] voidT
+  , mkMethod' "addWidget" "addWidgetWithStretch" [ptrT $ objT c_QWidget, intT] voidT
+  , mkMethod' "addWidget" "addWidgetWithStretchAndAlignment"
+    [ptrT $ objT c_QWidget, intT, bitspaceT bs_Alignment] voidT
+  , mkMethod' "insertLayout" "insertLayout" [intT, ptrT $ objT c_QLayout] voidT
+  , mkMethod' "insertLayout" "insertLayoutWithStretch" [intT, ptrT $ objT c_QLayout, intT] voidT
+    -- TODO insertSpacerItem
+  , mkMethod "insertSpacing" [intT, intT] voidT
+  , mkMethod' "insertStretch" "insertStretch" [intT] voidT
+  , mkMethod' "insertStretch" "insertStretchOf" [intT, intT] voidT
+  , mkMethod' "insertWidget" "insertWidget" [intT, ptrT $ objT c_QWidget] voidT
+  , mkMethod' "insertWidget" "insertWidgetWithStretch" [intT, ptrT $ objT c_QWidget, intT] voidT
+  , mkMethod' "insertWidget" "insertWidgetWithStretchAndAlignment"
+    [intT, ptrT $ objT c_QWidget, intT, bitspaceT bs_Alignment] voidT
+  , mkMethod "setStretch" [intT, intT] voidT
+  , mkMethod' "setStretchFactor" "setWidgetStretchFactor" [ptrT $ objT c_QWidget, intT] boolT
+  , mkMethod' "setStretchFactor" "setLayoutStretchFactor" [ptrT $ objT c_QLayout, intT] boolT
+  ] ++
+  mkProps
+  [ mkProp "direction" $ enumT e_Direction
+  , mkProp "spacing" intT
+  ]
+
+e_Direction =
+  makeQtEnum (ident1 "QBoxLayout" "Direction") [includeStd "QBoxLayout"]
+  [ (0, ["left", "to", "right"])
+  , (1, ["right", "to", "left"])
+  , (2, ["top", "to", "bottom"])
+  , (3, ["bottom", "to", "top"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QButtonGroup.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QButtonGroup.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QButtonGroup.hs
@@ -0,0 +1,92 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QButtonGroup (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, intT, objT, ptrT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QList (c_QListQAbstractButton)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Listener (
+  c_ListenerInt,
+  c_ListenerIntBool,
+  c_ListenerPtrQAbstractButton,
+  c_ListenerPtrQAbstractButtonBool,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton (c_QAbstractButton)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QButtonGroup"] $
+  (QtExport $ ExportClass c_QButtonGroup) :
+  map QtExportSignal signals
+
+c_QButtonGroup =
+  addReqIncludes [includeStd "QButtonGroup"] $
+  makeClass (ident "QButtonGroup") Nothing [c_QObject]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QObject]
+  ] $
+  collect
+  [ just $ mkMethod' "addButton" "addButton" [ptrT $ objT c_QAbstractButton] voidT
+  , just $ mkMethod' "addButton" "addButtonWithId" [ptrT $ objT c_QAbstractButton, intT] voidT
+  , test (qtVersion >= [4, 1]) $ mkConstMethod "button" [intT] $ ptrT $ objT c_QAbstractButton
+  , just $ mkConstMethod "buttons" [] $ objT c_QListQAbstractButton
+  , just $ mkConstMethod "checkedButton" [] $ ptrT $ objT c_QAbstractButton
+  , test (qtVersion >= [4, 1]) $ mkConstMethod "checkedId" [] intT
+  , test (qtVersion >= [4, 1]) $ mkConstMethod "id" [ptrT $ objT c_QAbstractButton] intT
+  , just $ mkMethod "removeButton" [ptrT $ objT c_QAbstractButton] voidT
+  , test (qtVersion >= [4, 1]) $ mkMethod "setId" [ptrT $ objT c_QAbstractButton, intT] voidT
+  ] ++
+  mkProps
+  [ mkProp "exclusive" boolT
+  ]
+
+signals =
+  collect
+  [ just $ makeSignal c_QButtonGroup "buttonClicked" c_ListenerPtrQAbstractButton
+  , just $ makeSignal c_QButtonGroup "buttonClickedId" c_ListenerInt
+  , test (qtVersion >= [4, 2]) $
+    makeSignal c_QButtonGroup "buttonPressed" c_ListenerPtrQAbstractButton
+  , test (qtVersion >= [4, 2]) $ makeSignal c_QButtonGroup "buttonPressedId" c_ListenerInt
+  , test (qtVersion >= [4, 2]) $
+    makeSignal c_QButtonGroup "buttonReleased" c_ListenerPtrQAbstractButton
+  , test (qtVersion >= [4, 2]) $ makeSignal c_QButtonGroup "buttonReleasedId" c_ListenerInt
+  , test (qtVersion >= [5, 2]) $
+    makeSignal c_QButtonGroup "buttonToggled" c_ListenerPtrQAbstractButtonBool
+  , test (qtVersion >= [5, 2]) $
+    makeSignal c_QButtonGroup "buttonToggledId" c_ListenerIntBool
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QCheckBox.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QCheckBox.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QCheckBox.hs
@@ -0,0 +1,59 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QCheckBox (
+  aModule,
+  c_QCheckBox,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkCtor,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (enumT, objT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_CheckState)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton (c_QAbstractButton)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QCheckBox"]
+  [ QtExport $ ExportClass c_QCheckBox ]
+
+c_QCheckBox =
+  addReqIncludes [includeStd "QCheckBox"] $
+  makeClass (ident "QCheckBox") Nothing [ c_QAbstractButton ]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithText" [objT c_QString]
+  , mkCtor "newWithTextAndParent" [objT c_QString, ptrT $ objT c_QWidget]
+  ] $
+  mkProps
+  [ mkProp "checkState" $ enumT e_CheckState
+  , mkBoolIsProp "tristate"
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDial.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDial.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDial.hs
@@ -0,0 +1,58 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QDial (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, intT, objT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (qreal)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSlider (c_QAbstractSlider)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QDial"]
+  [ QtExport $ ExportClass c_QDial ]
+
+c_QDial =
+  addReqIncludes [includeStd "QDial"] $
+  makeClass (ident "QDial") Nothing [c_QAbstractSlider]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  [ mkConstMethod "notchSize" [] intT
+  ] ++
+  mkProps
+  [ mkProp "notchTarget" qreal
+  , mkProp "notchesVisible" boolT
+  , mkProp "wrapping" boolT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDialog.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDialog.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDialog.hs
@@ -0,0 +1,81 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QDialog (
+  aModule,
+  c_QDialog,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_WindowFlags)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_Listener, c_ListenerInt)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QDialog"] $
+  QtExport (ExportClass c_QDialog) :
+  map QtExportSignal signals ++
+  [ QtExport $ ExportEnum e_DialogCode ]
+
+c_QDialog =
+  addReqIncludes [includeStd "QDialog"] $
+  makeClass (ident "QDialog") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithParentAndFlags" [ptrT $ objT c_QWidget, bitspaceT bs_WindowFlags]
+  ] $
+  [ mkMethod "accept" [] voidT
+  , mkMethod "done" [intT] voidT
+  , mkMethod "exec" [] intT
+  , mkMethod "open" [] voidT
+  , mkMethod "reject" [] voidT
+  ] ++
+  mkProps
+  [ mkBoolIsProp "modal"
+  , mkProp "result" intT
+  , mkBoolIsProp "sizeGripEnabled"
+  ]
+
+signals =
+  [ makeSignal c_QDialog "accepted" c_Listener
+  , makeSignal c_QDialog "finished" c_ListenerInt
+  , makeSignal c_QDialog "rejected" c_Listener
+  ]
+
+e_DialogCode =
+  makeQtEnum (ident1 "QDialog" "DialogCode") [includeStd "QDialog"]
+  [ (0, ["rejected"])
+  , (1, ["accepted"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDialogButtonBox.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDialogButtonBox.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDialogButtonBox.hs
@@ -0,0 +1,146 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QDialogButtonBox (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportBitspace, ExportClass, ExportEnum),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, enumT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QList (c_QListQAbstractButton)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_Orientation)
+import Graphics.UI.Qtah.Generator.Interface.Listener (
+  c_Listener,
+  c_ListenerPtrQAbstractButton,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton (c_QAbstractButton)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QPushButton (c_QPushButton)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+minVersion = [4, 2]
+
+aModule =
+  AQtModule $
+  makeQtModuleWithMinVersion ["Widgets", "QDialogButtonBox"] minVersion $
+  (QtExport $ ExportClass c_QDialogButtonBox) :
+  map QtExportSignal signals ++
+  map QtExport
+  [ ExportEnum e_ButtonLayout
+  , ExportEnum e_ButtonRole
+  , ExportEnum e_StandardButton
+  , ExportBitspace bs_StandardButtons
+  ]
+
+c_QDialogButtonBox =
+  addReqIncludes [includeStd "QDialogButtonBox"] $
+  makeClass (ident "QDialogButtonBox") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+    -- TODO Other ctors? v v
+  --, mkCtor "newWithOrientation" [enumT e_Orientation]
+  --, mkCtor "newWithOrientationAndParent" [enumT e_Orientation, ptrT $ objT c_QWidget]
+  --, mkCtor "newWithButtons" []
+  --, mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  --, mkCtor "new" []
+  --, mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  [ mkMethod' "addButton" "addButton" [ptrT $ objT c_QAbstractButton, enumT e_ButtonRole] voidT
+  , mkMethod' "addButton" "addButtonWithText"
+    [objT c_QString, enumT e_ButtonRole] $ ptrT $ objT c_QPushButton
+  , mkMethod' "addButton" "addStandardButton" [enumT e_StandardButton] $ ptrT $ objT c_QPushButton
+  , mkConstMethod "button" [enumT e_StandardButton] $ ptrT $ objT c_QPushButton
+  , mkConstMethod "buttonRole" [ptrT $ objT c_QAbstractButton] $ enumT e_ButtonRole
+  , mkConstMethod "buttons" [] $ objT c_QListQAbstractButton
+  , mkMethod "clear" [] voidT
+  , mkMethod "removeButton" [ptrT $ objT c_QAbstractButton] voidT
+  , mkConstMethod "standardButton" [ptrT $ objT c_QAbstractButton] $ enumT e_StandardButton
+  ] ++
+  mkProps
+  [ mkProp "centerButtons" boolT
+  , mkProp "orientation" $ enumT e_Orientation
+  , mkProp "standardButtons" $ bitspaceT bs_StandardButtons
+  ]
+
+signals =
+  [ makeSignal c_QDialogButtonBox "accepted" c_Listener
+  , makeSignal c_QDialogButtonBox "clicked" c_ListenerPtrQAbstractButton
+  , makeSignal c_QDialogButtonBox "helpRequested" c_Listener
+  , makeSignal c_QDialogButtonBox "rejected" c_Listener
+  ]
+
+e_ButtonLayout =
+  makeQtEnum (ident1 "QDialogButtonBox" "ButtonLayout") [includeStd "QDialogButtonBox"]
+  [ (0, ["win", "layout"])
+  , (1, ["mac", "layout"])
+  , (2, ["kde", "layout"])
+  , (3, ["gnome", "layout"])
+  ]
+
+e_ButtonRole =
+  makeQtEnum (ident1 "QDialogButtonBox" "ButtonRole") [includeStd "QDialogButtonBox"]
+  [ (-1, ["invalid", "role"])
+  , (0, ["accept", "role"])
+  , (1, ["reject", "role"])
+  , (2, ["destructive", "role"])
+  , (3, ["action", "role"])
+  , (4, ["help", "role"])
+  , (5, ["yes", "role"])
+  , (6, ["no", "role"])
+  , (7, ["reset", "role"])
+  , (8, ["apply", "role"])
+  ]
+
+(e_StandardButton, bs_StandardButtons) =
+  makeQtEnumBitspace (ident1 "QDialogButtonBox" "StandardButton") "StandardButtons"
+  [includeStd "QDialogButtonBox"]
+  [ (0x00000400, ["ok"])
+  , (0x00002000, ["open"])
+  , (0x00000800, ["save"])
+  , (0x00400000, ["cancel"])
+  , (0x00200000, ["close"])
+  , (0x00800000, ["discard"])
+  , (0x02000000, ["apply"])
+  , (0x04000000, ["reset"])
+  , (0x08000000, ["restore", "defaults"])
+  , (0x01000000, ["help"])
+  , (0x00001000, ["save", "all"])
+  , (0x00004000, ["yes"])
+  , (0x00008000, ["yes", "to", "all"])
+  , (0x00010000, ["no"])
+  , (0x00020000, ["no", "to", "all"])
+  , (0x00040000, ["abort"])
+  , (0x00080000, ["retry"])
+  , (0x00100000, ["ignore"])
+  , (0x00000000, ["no", "button"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDoubleSpinBox.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDoubleSpinBox.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QDoubleSpinBox.hs
@@ -0,0 +1,77 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QDoubleSpinBox (
+  aModule,
+  c_QDoubleSpinBox,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (doubleT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Listener (
+  c_ListenerDouble,
+  c_ListenerQString,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSpinBox (c_QAbstractSpinBox)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QDoubleSpinBox"] $
+  QtExport (ExportClass c_QDoubleSpinBox) :
+  map QtExportSignal signals
+
+c_QDoubleSpinBox =
+  addReqIncludes [includeStd "QDoubleSpinBox"] $
+  makeClass (ident "QDoubleSpinBox") Nothing [c_QAbstractSpinBox]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  [ mkConstMethod "cleanText" [] $ objT c_QString
+  , mkMethod "setRange" [doubleT, doubleT] voidT
+  , mkConstMethod "textFromValue" [doubleT] $ objT c_QString
+  , mkConstMethod "valueFromText" [objT c_QString] doubleT
+  ] ++
+  mkProps
+  [ mkProp "decimals" intT
+  , mkProp "maximum" doubleT
+  , mkProp "minimum" doubleT
+  , mkProp "prefix" $ objT c_QString
+  , mkProp "singleStep" doubleT
+  , mkProp "suffix" $ objT c_QString
+  , mkProp "value" doubleT
+  ]
+
+signals =
+  [ makeSignal' c_QDoubleSpinBox "valueChanged" "valueChangedDouble" c_ListenerDouble
+  , makeSignal' c_QDoubleSpinBox "valueChanged" "valueChangedString" c_ListenerQString
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QFileDialog.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QFileDialog.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QFileDialog.hs
@@ -0,0 +1,198 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QFileDialog (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportBitspace, ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  mkStaticMethod',
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, enumT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QDir (bs_Filters, c_QDir)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.QStringList (c_QStringList)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_WindowFlags)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerQString)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QDialog (c_QDialog)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QFileDialog"] $
+  [ QtExport $ ExportClass c_QFileDialog
+  , QtExport $ ExportEnum e_AcceptMode
+  , QtExport $ ExportEnum e_DialogLabel
+  , QtExport $ ExportEnum e_FileMode
+  , QtExport $ ExportEnum e_Option
+  , QtExport $ ExportBitspace bs_Options
+  , QtExport $ ExportEnum e_ViewMode
+  ] ++ map QtExportSignal signals
+
+c_QFileDialog =
+  addReqIncludes [includeStd "QFileDialog"] $
+  makeClass (ident "QFileDialog") Nothing [c_QDialog]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithParentAndFlags" [ptrT $ objT c_QWidget, bitspaceT bs_WindowFlags]
+  , mkCtor "newWithParentAndCaption" [ptrT $ objT c_QWidget, objT c_QString]
+  , mkCtor "newWithParentAndCaptionAndDirectory"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString]
+  , mkCtor "newWithParentAndCaptionAndDirectoryAndFilter"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString, objT c_QString]
+  ] $
+  collect
+  [ just $ mkConstMethod "directory" [] $ objT c_QDir
+    -- TODO directoryUrl (>=5.2)
+  , just $ mkStaticMethod' "getExistingDirectory" "getExistingDirectory"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString] $ objT c_QString
+  , just $ mkStaticMethod' "getExistingDirectory" "getExistingDirectoryWithOptions"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString, bitspaceT bs_Options] $ objT c_QString
+    -- TODO getExistingDirectoryUrl (>=5.2)
+  , just $ mkStaticMethod' "getOpenFileName" "getOpenFileName"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString, objT c_QString] $ objT c_QString
+  , just $ mkStaticMethod' "getOpenFileName" "getOpenFileNameWithOptions"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString,
+     objT c_QString, ptrT $ objT c_QString, bitspaceT bs_Options] $
+    objT c_QString
+  , just $ mkStaticMethod' "getOpenFileNames" "getOpenFileNames"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString, objT c_QString] $ objT c_QStringList
+  , just $ mkStaticMethod' "getOpenFileNames" "getOpenFileNamesWithOptions"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString,
+     objT c_QString, ptrT $ objT c_QString, bitspaceT bs_Options] $
+    objT c_QStringList
+    -- TODO getOpenFileUrl (>=5.2)
+    -- TODO getOpenFileUrls (>=5.2)
+  , just $ mkStaticMethod' "getSaveFileName" "getSaveFileName"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString, objT c_QString] $ objT c_QString
+  , just $ mkStaticMethod' "getSaveFileName" "getSaveFileNameWithOptions"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString,
+     objT c_QString, ptrT $ objT c_QString, bitspaceT bs_Options] $
+    objT c_QString
+    -- TODO getSaveFileUrl (>=5.2)
+
+    -- TODO iconProvider
+    -- TODO itemDelegate
+  , just $ mkConstMethod "labelText" [enumT e_DialogLabel] $ objT c_QString
+    -- TODO open (>=4.5)
+    -- TODO proxyModel
+    -- TODO restoreState (>=4.3)
+    -- TODO saveState (>=4.3)
+  , just $ mkMethod "selectFile" [objT c_QString] voidT
+    -- TODO selectMimeTypeFilter (>=5.2)
+  , just $ mkMethod "selectNameFilter" [objT c_QString] voidT
+    -- TODO selectUrl (>=5.2)
+  , just $ mkConstMethod "selectedFiles" [] $ objT c_QStringList
+  , test (qtVersion >= [4, 4]) $ mkConstMethod "selectedNameFilter" [] $ objT c_QString
+    -- TODO selectedUrls (>=5.2)
+  , just $ mkMethod' "setDirectory" "setDirectory" [objT c_QDir] voidT
+  , just $ mkMethod' "setDirectory" "setDirectoryPath" [objT c_QString] voidT
+    -- TODO setDirectoryUrl(QUrl) (>=5.2)
+    -- TODO setHistory
+    -- TODO setIconProvider
+    -- TODO setItemDelegate
+  , just $ mkMethod "setLabelText" [enumT e_DialogLabel, objT c_QString] voidT
+  , test (qtVersion >= [4, 4]) $ mkMethod "setNameFilter" [objT c_QString] voidT
+  , test (qtVersion >= [4, 5]) $ mkMethod "setOption" [enumT e_Option, boolT] voidT
+    -- TODO setProxyModel (>=4.3)
+    -- TODO testOption (>=4.5)
+  ] ++
+  (mkProps . collect)
+  [ just $ mkProp "acceptMode" $ enumT e_AcceptMode
+  , just $ mkProp "defaultSuffix" $ objT c_QString
+  , just $ mkProp "fileMode" $ enumT e_FileMode
+  , test (qtVersion >= [4, 4]) $ mkProp "filter" $ bitspaceT bs_Filters
+  , just $ mkProp "history" $ objT c_QStringList
+  , test (qtVersion >= [5, 2]) $ mkProp "mimeTypeFilters" $ objT c_QStringList
+  , test (qtVersion >= [4, 4]) $ mkProp "nameFilters" $ objT c_QStringList
+  , test (qtVersion >= [4, 5]) $ mkProp "options" $ bitspaceT bs_Options
+    -- TODO sidebarUrls (>=4.3)
+  , just $ mkProp "viewMode" $ enumT e_ViewMode
+  ]
+
+signals =
+  collect
+  [ just $ makeSignal c_QFileDialog "currentChanged" c_ListenerQString
+    -- TODO currentUrlChanged (>=5.2)
+  , just $ makeSignal c_QFileDialog "directoryEntered" c_ListenerQString
+    -- TODO directoryUrlEntered (>=5.2)
+  , just $ makeSignal c_QFileDialog "fileSelected" c_ListenerQString
+    -- TODO filesSelected
+  , test (qtVersion >= [4, 3]) $ makeSignal c_QFileDialog "filterSelected" c_ListenerQString
+    -- TODO urlSelected (>=5.2)
+    -- TODO urlsSelected (>=5.2)
+  ]
+
+e_AcceptMode =
+  makeQtEnum (ident1 "QFileDialog" "AcceptMode") [includeStd "QFileDialog"]
+  [ (0, ["accept", "open"])
+  , (1, ["accept", "save"])
+  ]
+
+e_DialogLabel =
+  makeQtEnum (ident1 "QFileDialog" "DialogLabel") [includeStd "QFileDialog"]
+  [ (0, ["look", "in"])
+  , (1, ["file", "name"])
+  , (2, ["file", "type"])
+  , (3, ["accept"])
+  , (4, ["reject"])
+  ]
+
+e_FileMode =
+  makeQtEnum (ident1 "QFileDialog" "FileMode") [includeStd "QFileDialog"] $
+  collect
+  [ just (0, ["any", "file"])
+  , just (1, ["existing", "file"])
+  , just (2, ["directory"])
+  , just (3, ["existing", "files"])
+  , test (qtVersion < [4, 5]) $ (4, ["directory", "only"])
+  ]
+
+(e_Option, bs_Options) =
+  makeQtEnumBitspace (ident1 "QFileDialog" "Option") "Options" [includeStd "QFileDialog"]
+  [ (0x1, ["show", "dirs", "only"])
+  , (0x2, ["dont", "resolve", "symlinks"])
+  , (0x4, ["dont", "confirm", "overwrite"])
+  , (0x8, ["dont", "use", "sheet"])
+  , (0x10, ["dont", "use", "native", "dialog"])
+  , (0x20, ["read", "only"])
+  , (0x40, ["hide", "name", "filter", "details"])
+  , (0x80, ["dont", "use", "custom", "directory", "icons"])
+  ]
+
+e_ViewMode =
+  makeQtEnum (ident1 "QFileDialog" "ViewMode") [includeStd "QFileDialog"]
+  [ (0, ["detail"])
+  , (1, ["list"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QFormLayout.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QFormLayout.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QFormLayout.hs
@@ -0,0 +1,137 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QFormLayout (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass, ExportEnum),
+  MethodApplicability (MConst),
+  Purity (Nonpure),
+  addReqIncludes,
+  ident,
+  ident1,
+  ident2,
+  includeLocal,
+  includeStd,
+  makeClass,
+  makeFnMethod,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, constT, enumT, intT, objT, ptrT, refT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QLayout (c_QLayout)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QLayoutItem (c_QLayoutItem)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+minVersion = [4, 4]
+
+aModule =
+  AQtModule $
+  makeQtModuleWithMinVersion ["Widgets", "QFormLayout"] minVersion
+  [ QtExport $ ExportClass c_QFormLayout
+  , QtExport $ ExportEnum e_FieldGrowthPolicy
+  , QtExport $ ExportEnum e_ItemRole
+  , QtExport $ ExportEnum e_RowWrapPolicy
+  ]
+
+c_QFormLayout =
+  addReqIncludes [includeStd "QFormLayout",
+                  includeLocal "wrap_qformlayout.hpp"] $
+  makeClass (ident "QFormLayout") Nothing [c_QLayout]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  [ mkMethod' "addRow" "addRowWidgetWidget" [ptrT $ objT c_QWidget, ptrT $ objT c_QWidget] voidT
+  , mkMethod' "addRow" "addRowWidgetLayout" [ptrT $ objT c_QWidget, ptrT $ objT c_QLayout] voidT
+  , mkMethod' "addRow" "addRowStringWidget" [objT c_QString, ptrT $ objT c_QWidget] voidT
+  , mkMethod' "addRow" "addRowStringLayout" [objT c_QString, ptrT $ objT c_QLayout] voidT
+  , mkMethod' "addRow" "addRowWidget" [ptrT $ objT c_QWidget] voidT
+  , mkMethod' "addRow" "addRowLayout" [ptrT $ objT c_QLayout] voidT
+  , makeFnMethod (ident2 "qtah" "qformlayout" "getItemRow") "getItemRow" MConst Nonpure
+    [refT $ constT $ objT c_QFormLayout, intT] intT
+  , makeFnMethod (ident2 "qtah" "qformlayout" "getItemRole") "getItemRole" MConst Nonpure
+    [refT $ constT $ objT c_QFormLayout, intT] $ enumT e_ItemRole
+  , makeFnMethod (ident2 "qtah" "qformlayout" "getLayoutRow") "getLayoutRow" MConst Nonpure
+    [refT $ constT $ objT c_QFormLayout, ptrT $ objT c_QLayout] intT
+  , makeFnMethod (ident2 "qtah" "qformlayout" "getLayoutRole") "getLayoutRole" MConst Nonpure
+    [refT $ constT $ objT c_QFormLayout, ptrT $ objT c_QLayout] $ enumT e_ItemRole
+  , makeFnMethod (ident2 "qtah" "qformlayout" "getWidgetRow") "getWidgetRow" MConst Nonpure
+    [refT $ constT $ objT c_QFormLayout, ptrT $ objT c_QWidget] intT
+  , makeFnMethod (ident2 "qtah" "qformlayout" "getWidgetRole") "getWidgetRole" MConst Nonpure
+    [refT $ constT $ objT c_QFormLayout, ptrT $ objT c_QWidget] $ enumT e_ItemRole
+  , mkMethod' "insertRow" "insertRowWidgetWidget"
+    [intT, ptrT $ objT c_QWidget, ptrT $ objT c_QWidget] voidT
+  , mkMethod' "insertRow" "insertRowWidgetLayout"
+    [intT, ptrT $ objT c_QWidget, ptrT $ objT c_QLayout] voidT
+  , mkMethod' "insertRow" "insertRowStringWidget"
+    [intT, objT c_QString, ptrT $ objT c_QWidget] voidT
+  , mkMethod' "insertRow" "insertRowStringLayout"
+    [intT, objT c_QString, ptrT $ objT c_QLayout] voidT
+  , mkMethod' "insertRow" "insertRowWidget" [intT, ptrT $ objT c_QWidget] voidT
+  , mkMethod' "insertRow" "insertRowLayout" [intT, ptrT $ objT c_QLayout] voidT
+  , mkConstMethod "itemAt" [intT, enumT e_ItemRole] $ ptrT $ objT c_QLayoutItem
+  , mkConstMethod' "labelForField" "labelForFieldWidget"
+    [ptrT $ objT c_QWidget] $ ptrT $ objT c_QWidget
+  , mkConstMethod' "labelForField" "labelForFieldLayout"
+    [ptrT $ objT c_QLayout] $ ptrT $ objT c_QWidget
+  , mkConstMethod "rowCount" [] intT
+  , mkMethod "setItem" [intT, enumT e_ItemRole, ptrT $ objT c_QLayoutItem] voidT
+  , mkMethod "setLayout" [intT, enumT e_ItemRole, ptrT $ objT c_QLayout] voidT
+  , mkMethod "setWidget" [intT, enumT e_ItemRole, ptrT $ objT c_QWidget] voidT
+  ] ++
+  mkProps
+  [ mkProp "fieldGrowthPolicy" $ enumT e_FieldGrowthPolicy
+  , mkProp "formAlignment" $ bitspaceT bs_Alignment
+  , mkProp "horizontalSpacing" intT
+  , mkProp "labelAlignment" $ bitspaceT bs_Alignment
+  , mkProp "rowWrapPolicy" $ enumT e_RowWrapPolicy
+  , mkProp "spacing" intT
+  , mkProp "verticalSpacing" intT
+  ]
+
+e_FieldGrowthPolicy =
+  makeQtEnum (ident1 "QFormLayout" "FieldGrowthPolicy") [includeStd "QFormLayout"]
+  [ (0, ["fields", "stay", "at", "size", "hint"])
+  , (1, ["expanding", "fields", "grow"])
+  , (2, ["all", "non", "fixed", "fields", "grow"])
+  ]
+
+e_ItemRole =
+  makeQtEnum (ident1 "QFormLayout" "ItemRole") [includeStd "QFormLayout"]
+  [ (0, ["label", "role"])
+  , (1, ["field", "role"])
+  , (2, ["spanning", "role"])
+  ]
+
+e_RowWrapPolicy =
+  makeQtEnum (ident1 "QFormLayout" "RowWrapPolicy") [includeStd "QFormLayout"]
+  [ (0, ["dont", "wrap", "rows"])
+  , (1, ["wrap", "long", "rows"])
+  , (2, ["wrap", "all", "rows"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QFrame.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QFrame.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QFrame.hs
@@ -0,0 +1,91 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QFrame (
+  aModule,
+  c_QFrame,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (enumT, intT, objT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QFrame"]
+  [ QtExport $ ExportClass c_QFrame
+  , QtExport $ ExportEnum e_Shadow
+  , QtExport $ ExportEnum e_Shape
+  , QtExport $ ExportEnum e_StyleMask
+  ]
+
+c_QFrame =
+  addReqIncludes [includeStd "QFrame"] $
+  makeClass (ident "QFrame") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+    -- TODO QFrame(QWidget*, Qt::WindowFlags)
+  ] $
+  [ mkConstMethod "frameWidth" [] intT
+  ] ++
+  mkProps
+  [ mkProp "frameRect" $ objT c_QRect
+  , mkProp "frameShadow" $ enumT e_Shadow
+  , mkProp "frameShape" $ enumT e_Shape
+  , mkProp "frameStyle" intT
+  , mkProp "lineWidth" intT
+  , mkProp "midLineWidth" intT
+  ]
+
+e_Shadow =
+  makeQtEnum (ident1 "QFrame" "Shadow") [includeStd "QFrame"]
+  [ (0x0010, ["plain"])
+  , (0x0020, ["raised"])
+  , (0x0030, ["sunken"])
+  ]
+
+e_Shape =
+  makeQtEnum (ident1 "QFrame" "Shape") [includeStd "QFrame"]
+  [ (0x0000, ["no", "frame"])
+  , (0x0001, ["box"])
+  , (0x0002, ["panel"])
+  , (0x0003, ["win", "panel"])
+  , (0x0004, ["h", "line"])
+  , (0x0005, ["v", "line"])
+  , (0x0006, ["styled", "panel"])
+  ]
+
+e_StyleMask =
+  makeQtEnum (ident1 "QFrame" "StyleMask") [includeStd "QFrame"]
+  [ (0x000f, ["shape", "mask"])
+  , (0x00f0, ["shadow", "mask"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QGridLayout.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QGridLayout.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QGridLayout.hs
@@ -0,0 +1,112 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QGridLayout (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  MethodApplicability (MConst, MNormal),
+  Purity (Nonpure),
+  addReqIncludes,
+  ident,
+  ident2,
+  includeLocal,
+  includeStd,
+  makeClass,
+  makeFnMethod,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, constT, enumT, intT, objT, ptrT, refT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment, e_Corner)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QLayout (c_QLayout)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QLayoutItem (c_QLayoutItem)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QGridLayout"]
+  [ QtExport $ ExportClass c_QGridLayout ]
+
+c_QGridLayout =
+  addReqIncludes [includeStd "QGridLayout",
+                  includeLocal "wrap_qgridlayout.hpp"] $
+  makeClass (ident "QGridLayout") Nothing [c_QLayout]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  collect
+  [ just $ mkMethod' "addItem" "addItem" [ptrT $ objT c_QLayoutItem, intT, intT] voidT
+  , just $ mkMethod' "addItem" "addItemWithSpan"
+    [ptrT $ objT c_QLayoutItem, intT, intT, intT, intT] voidT
+  , just $ mkMethod' "addItem" "addItemWithSpanAndAlignment"
+    [ptrT $ objT c_QLayoutItem, intT, intT, intT, intT, bitspaceT bs_Alignment] voidT
+  , just $ mkMethod' "addLayout" "addLayout" [ptrT $ objT c_QLayout, intT, intT] voidT
+  , just $ mkMethod' "addLayout" "addLayoutWithSpan"
+    [ptrT $ objT c_QLayout, intT, intT, intT, intT] voidT
+  , just $ mkMethod' "addLayout" "addLayoutWithSpanAndAlignment"
+    [ptrT $ objT c_QLayout, intT, intT, intT, intT, bitspaceT bs_Alignment] voidT
+  , just $ mkMethod' "addWidget" "addWidget" [ptrT $ objT c_QWidget, intT, intT] voidT
+  , just $ mkMethod' "addWidget" "addWidgetWithSpan"
+    [ptrT $ objT c_QWidget, intT, intT, intT, intT] voidT
+  , just $ mkMethod' "addWidget" "addWidgetWithSpanAndAlignment"
+    [ptrT $ objT c_QWidget, intT, intT, intT, intT, bitspaceT bs_Alignment] voidT
+  , just $ mkConstMethod "cellRect" [intT, intT] $ objT c_QRect
+  , just $ mkConstMethod "columnCount" [] intT
+  , just $ mkConstMethod "columnMinimumWidth" [intT] intT
+  , just $ mkConstMethod "columnStretch" [intT] intT
+  , just $ makeFnMethod (ident2 "qtah" "qgridlayout" "getItemRow") "getItemRow"
+    getItemPositionAppl Nonpure [getItemPositionThis, intT] intT
+  , just $ makeFnMethod (ident2 "qtah" "qgridlayout" "getItemColumn") "getItemColumn"
+    getItemPositionAppl Nonpure [getItemPositionThis, intT] intT
+  , just $ makeFnMethod (ident2 "qtah" "qgridlayout" "getItemRowSpan") "getItemRowSpan"
+    getItemPositionAppl Nonpure [getItemPositionThis, intT] intT
+  , just $ makeFnMethod (ident2 "qtah" "qgridlayout" "getItemColumnSpan") "getItemColumnSpan"
+    getItemPositionAppl Nonpure [getItemPositionThis, intT] intT
+  , test (qtVersion >= [4, 4]) $
+    mkConstMethod "itemAtPosition" [intT, intT] $ ptrT $ objT c_QLayoutItem
+  , just $ mkConstMethod "rowCount" [] intT
+  , just $ mkConstMethod "rowMinimumHeight" [intT] intT
+  , just $ mkConstMethod "rowStretch" [intT] intT
+  , just $ mkMethod "setColumnMinimumWidth" [intT, intT] voidT
+  , just $ mkMethod "setColumnStretch" [intT, intT] voidT
+  , just $ mkMethod "setRowMinimumHeight" [intT, intT] voidT
+  , just $ mkMethod "setRowStretch" [intT, intT] voidT
+  , just $ mkConstMethod "spacing" [] intT
+  ] ++
+  (mkProps . collect)
+  [ test (qtVersion >= [4, 3]) $ mkProp "horizontalSpacing" intT
+  , test (qtVersion >= [4, 3]) $ mkProp "verticalSpacing" intT
+  , just $ mkProp "originCorner" $ enumT e_Corner
+  ]
+
+  where (getItemPositionAppl, getItemPositionThis) =
+          if qtVersion >= [5, 0]
+          then (MConst, refT $ constT $ objT c_QGridLayout)
+          else (MNormal, refT $ objT c_QGridLayout)
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QGroupBox.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QGroupBox.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QGroupBox.hs
@@ -0,0 +1,72 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QGroupBox (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkCtor,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, objT, ptrT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment)
+import Graphics.UI.Qtah.Generator.Interface.Listener (
+  c_ListenerBool,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QGroupBox"] $
+  (QtExport $ ExportClass c_QGroupBox) :
+  map QtExportSignal signals
+
+c_QGroupBox =
+  addReqIncludes [includeStd "QGroupBox"] $
+  makeClass (ident "QGroupBox") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithTitle" [objT c_QString]
+  , mkCtor "newWithTitleAndParent" [objT c_QString, ptrT $ objT c_QWidget]
+  ] $
+  mkProps
+  [ mkProp "alignment" $ bitspaceT bs_Alignment
+  , mkBoolIsProp "checkable"
+  , mkBoolIsProp "checked"
+  , mkBoolIsProp "flat"
+  , mkProp "title" $ objT c_QString
+  ]
+
+signals =
+  collect
+  [ test (qtVersion >= [4, 2]) $ makeSignal c_QGroupBox "clicked" c_ListenerBool
+  , just $ makeSignal c_QGroupBox "toggled" c_ListenerBool
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QHBoxLayout.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QHBoxLayout.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QHBoxLayout.hs
@@ -0,0 +1,48 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QHBoxLayout (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (objT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QBoxLayout (c_QBoxLayout)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QHBoxLayout"]
+  [ QtExport $ ExportClass c_QHBoxLayout ]
+
+c_QHBoxLayout =
+  addReqIncludes [includeStd "QHBoxLayout"] $
+  makeClass (ident "QHBoxLayout") Nothing [c_QBoxLayout]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ]
+  []
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLabel.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLabel.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLabel.hs
@@ -0,0 +1,88 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QLabel (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkBoolHasProp,
+  mkConstMethod,
+  mkCtor,
+  mkMethod',
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, doubleT, enumT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment, e_TextFormat)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerQString)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QFrame (c_QFrame)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QLabel"] $
+  QtExport (ExportClass c_QLabel) :
+  map QtExportSignal signals
+
+c_QLabel =
+  addReqIncludes [includeStd "QLabel"] $
+  makeClass (ident "QLabel") Nothing [c_QFrame]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithText" [objT c_QString]
+  , mkCtor "newWithTextAndParent" [objT c_QString, ptrT $ objT c_QWidget]
+    -- TODO Ctors taking Qt::WindowFlags.
+  ] $
+  [ mkMethod "clear" [] voidT
+  , mkConstMethod "hasSelectedText" [] boolT
+  , mkConstMethod "selectedText" [] $ objT c_QString
+  , mkConstMethod "selectionStart" [] intT
+  , mkMethod' "setNum" "setInt" [intT] voidT
+  , mkMethod' "setNum" "setDouble" [doubleT] voidT
+  , mkMethod "setSelection" [intT, intT] voidT
+  ] ++
+  mkProps
+  [ mkProp "alignment" $ bitspaceT bs_Alignment
+  , mkProp "buddy" $ ptrT $ objT c_QWidget
+  , mkProp "indent" intT
+  , mkProp "margin" intT
+    -- TODO movie
+  , mkProp "openExternalLinks" boolT
+    -- TODO picture
+    -- TODO pixmap
+  , mkBoolHasProp "scaledContents"
+  , mkProp "text" $ objT c_QString
+  , mkProp "textFormat" $ enumT e_TextFormat
+    -- TODO textInteractionFlags
+  , mkProp "wordWrap" boolT
+  ]
+
+signals =
+  [ makeSignal c_QLabel "linkActivated" c_ListenerQString
+  , makeSignal c_QLabel "linkHovered" c_ListenerQString
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLayout.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLayout.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLayout.hs
@@ -0,0 +1,104 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QLayout (
+  aModule,
+  c_QLayout,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkConstMethod,
+  mkMethod,
+  mkMethod',
+  mkStaticMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, enumT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QMargins (c_QMargins)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QLayoutItem (c_QLayoutItem)
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QLayout"]
+  [ QtExport $ ExportClass c_QLayout
+  , QtExport $ ExportEnum e_SizeConstraint
+  ]
+
+c_QLayout =
+  addReqIncludes [includeStd "QLayout"] $
+  makeClass (ident "QLayout") Nothing [c_QObject, c_QLayoutItem]
+  [] $  -- Abstract.
+  collect
+  [ just $ mkMethod "activate" [] boolT
+  , just $ mkMethod "addItem" [ptrT $ objT c_QLayoutItem] voidT
+  , just $ mkMethod "addWidget" [ptrT $ objT c_QWidget] voidT
+  , just $ mkStaticMethod "closestAcceptableSize"
+    [ptrT $ objT c_QWidget, objT c_QSize] $ objT c_QSize
+  , test (qtVersion >= [4, 6]) $ mkConstMethod "contentsMargins" [] $ objT c_QMargins
+  , test (qtVersion >= [4, 3]) $ mkConstMethod "contentsRect" [] $ objT c_QRect
+  , just $ mkConstMethod "count" [] intT
+  , just $ mkConstMethod "indexOf" [ptrT $ objT c_QWidget] intT
+  , just $ mkConstMethod "itemAt" [intT] $ ptrT $ objT c_QLayoutItem
+  , just $ mkConstMethod "parentWidget" [] $ ptrT $ objT c_QWidget
+  , just $ mkMethod "removeItem" [ptrT $ objT c_QLayoutItem] voidT
+  , just $ mkMethod "removeWidget" [ptrT $ objT c_QWidget] voidT
+  , just $ mkMethod' "setAlignment" "setAlignment" [bitspaceT bs_Alignment] voidT
+  , just $ mkMethod' "setAlignment" "setLayoutAlignment"
+    [ptrT $ objT c_QLayout, bitspaceT bs_Alignment] boolT
+  , just $ mkMethod' "setAlignment" "setWidgetAlignment"
+    [ptrT $ objT c_QWidget, bitspaceT bs_Alignment] boolT
+  , test (qtVersion >= [4, 6]) $ mkMethod' "setContentsMargins" "setContentsMargins"
+    [objT c_QMargins] voidT
+  , test (qtVersion >= [4, 3]) $ mkMethod' "setContentsMargins" "setContentsMarginsRaw"
+    [intT, intT, intT, intT] voidT
+  , just $ mkMethod "takeAt" [intT] $ ptrT $ objT c_QLayoutItem
+  , just $ mkMethod "update" [] voidT
+  ] ++
+  mkProps
+  [ mkBoolIsProp "enabled"
+  , mkProp "menuBar" $ ptrT $ objT c_QWidget
+  , mkProp "sizeConstraint" $ enumT e_SizeConstraint
+  , mkProp "spacing" intT
+  ]
+
+e_SizeConstraint =
+  makeQtEnum (ident1 "QLayout" "SizeConstraint") [includeStd "QLayout"]
+  [ (0, ["set", "default", "size", "constraint"])
+  , (1, ["set", "no", "constraint"])
+  , (2, ["set", "minimum", "size"])
+  , (3, ["set", "fixed", "size"])
+  , (4, ["set", "maximum", "size"])
+  , (5, ["set", "min", "and", "max", "size"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLayout.hs-boot b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLayout.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLayout.hs-boot
@@ -0,0 +1,24 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QLayout (
+  c_QLayout,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (Class)
+
+c_QLayout :: Class
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLayoutItem.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLayoutItem.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLayoutItem.hs
@@ -0,0 +1,70 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QLayoutItem (
+  aModule,
+  c_QLayoutItem,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment, bs_Orientations)
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Widgets.QLayout (c_QLayout)
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QLayoutItem"]
+  [ QtExport $ ExportClass c_QLayoutItem ]
+
+c_QLayoutItem =
+  addReqIncludes [includeStd "QLayoutItem"] $
+  makeClass (ident "QLayoutItem") Nothing []
+  [] $  -- Abstract.
+  [ -- TODO controlTypes
+    mkConstMethod "expandingDirections" [] $ bitspaceT bs_Orientations
+  , mkConstMethod "hasHeightForWidth" [] boolT
+  , mkConstMethod "heightForWidth" [intT] intT
+  , mkMethod "invalidate" [] voidT
+  , mkConstMethod "isEmpty" [] boolT
+  , mkMethod "layout" [] $ ptrT $ objT c_QLayout
+  , mkConstMethod "maximumSize" [] $ objT c_QSize
+  , mkConstMethod "minimumHeightForWidth" [intT] intT
+  , mkConstMethod "minimumSize" [] $ objT c_QSize
+  , mkConstMethod "sizeHint" [] $ objT c_QSize
+    -- TODO spacerItem
+  , mkConstMethod "widget" [] $ ptrT $ objT c_QWidget
+  ] ++
+  mkProps
+  [ mkProp "alignment" $ bitspaceT bs_Alignment
+  , mkProp "geometry" $ objT c_QRect
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLineEdit.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLineEdit.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QLineEdit.hs
@@ -0,0 +1,133 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QLineEdit (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkBoolHasProp,
+  mkBoolIsProp,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, constT, enumT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QMargins (c_QMargins)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment, e_CursorMoveStyle)
+import Graphics.UI.Qtah.Generator.Interface.Gui.QValidator (c_QValidator)
+import Graphics.UI.Qtah.Generator.Interface.Listener (
+  c_Listener,
+  c_ListenerIntInt,
+  c_ListenerQString,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QMenu (c_QMenu)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QLineEdit"] $
+  QtExport (ExportClass c_QLineEdit) :
+  map QtExportSignal signals ++
+  [ QtExport $ ExportEnum e_EchoMode ]
+
+c_QLineEdit =
+  addReqIncludes [includeStd "QLineEdit"] $
+  makeClass (ident "QLineEdit") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithText" [objT c_QString]
+  , mkCtor "newWithTextAndParent" [objT c_QString, ptrT $ objT c_QWidget]
+  ] $
+  [ mkMethod "backspace" [] voidT
+  , mkMethod "clear" [] voidT
+  , mkConstMethod "copy" [] voidT
+  , mkMethod "createStandardContextMenu" [] $ ptrT $ objT c_QMenu
+  , mkMethod "cursorBackward" [boolT, intT] voidT
+  , mkMethod "cursorForward" [boolT, intT] voidT
+  , mkMethod "cursorPositionAt" [objT c_QPoint] intT
+  , mkMethod "cursorWordBackward" [boolT] voidT
+  , mkMethod "cursorWordForward" [boolT] voidT
+  , mkMethod "cut" [] voidT
+  , mkMethod "del" [] voidT
+  , mkMethod "deselect" [] voidT
+  , mkConstMethod "displayText" [] $ objT c_QString
+  , mkMethod "end" [boolT] voidT
+  , mkConstMethod "hasAcceptableInput" [] boolT
+  , mkConstMethod "hasSelectedText" [] boolT
+  , mkMethod "home" [boolT] voidT
+  , mkMethod "insert" [objT c_QString] voidT
+  , mkConstMethod "isRedoAvailable" [] boolT
+  , mkConstMethod "isUndoAvailable" [] boolT
+  , mkMethod "paste" [] voidT
+  , mkMethod "redo" [] voidT
+  , mkMethod "selectAll" [] voidT
+  , mkConstMethod "selectedText" [] $ objT c_QString
+  , mkConstMethod "selectionStart" [] intT
+  , mkMethod "setSelection" [intT, intT] voidT
+  , mkMethod' "setTextMargins" "setTextMargins" [objT c_QMargins] voidT
+  , mkMethod' "setTextMargins" "setTextMarginsRaw" [intT, intT, intT, intT] voidT
+  , mkConstMethod "textMargins" [] $ objT c_QMargins
+  , mkMethod "undo" [] voidT
+  ] ++
+  mkProps
+  [ mkProp "alignment" $ bitspaceT bs_Alignment
+    -- TODO completer
+  , mkProp "cursorMoveStyle" $ enumT e_CursorMoveStyle
+  , mkProp "cursorPosition" intT
+  , mkProp "dragEnabled" boolT
+  , mkProp "echoMode" $ enumT e_EchoMode
+  , mkBoolHasProp "frame"
+  , mkProp "inputMask" $ objT c_QString
+  , mkProp "maxLength" intT
+  , mkBoolIsProp "modified"
+  , mkProp "placeholderText" $ objT c_QString
+  , mkBoolIsProp "readOnly"
+  , mkProp "text" $ objT c_QString
+  , mkProp "validator" $ ptrT $ constT $ objT c_QValidator
+  ]
+
+signals =
+  [ makeSignal c_QLineEdit "cursorPositionChanged" c_ListenerIntInt
+  , makeSignal c_QLineEdit "editingFinished" c_Listener
+  , makeSignal c_QLineEdit "returnPressed" c_Listener
+  , makeSignal c_QLineEdit "selectionChanged" c_Listener
+  , makeSignal c_QLineEdit "textEdited" c_ListenerQString
+  , makeSignal c_QLineEdit "textChanged" c_ListenerQString
+  ]
+
+e_EchoMode =
+  makeQtEnum (ident1 "QLineEdit" "EchoMode") [includeStd "QLineEdit"]
+  [ (0, ["normal"])
+  , (1, ["no", "echo"])
+  , (2, ["password"])
+  , (3, ["password", "echo", "on", "edit"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMainWindow.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMainWindow.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMainWindow.hs
@@ -0,0 +1,98 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QMainWindow (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, objT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerQSize)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QMenu (c_QMenu)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QMenuBar (c_QMenuBar)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QStatusBar (c_QStatusBar)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QMainWindow"] $
+  QtExport (ExportClass c_QMainWindow) :
+  map QtExportSignal signals
+
+c_QMainWindow =
+  addReqIncludes [includeStd "QMainWindow"] $
+  makeClass (ident "QMainWindow") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+    -- TODO Ctor with Qt::WindowFlags.
+  ] $
+  [ -- TODO addDockWidget
+    -- TODO addToolBar
+    -- TODO addToolBarBreak
+    -- TODO corner
+    mkMethod "createPopupMenu" [] $ ptrT $ objT c_QMenu
+    -- TODO dockWidgetArea
+    -- TODO insertToolBar
+    -- TODO insertToolBarBreak
+    -- TODO removeDockWidget
+    -- TODO restoreState
+    -- TODO saveState
+    -- TODO setCorner
+    -- TODO setTabPosition
+    -- TODO setTabShape
+    -- TODO splitDockWidget
+    -- TODO tabifiedDockWidgets
+    -- TODO tabifyDockWidget
+    -- TODO tabPosition
+    -- TODO tabShape
+    -- TODO toolBarArea
+    -- TODO toolBarBreak
+  ] ++
+  mkProps
+  [ mkBoolIsProp "animated"
+  , mkProp "centralWidget" $ ptrT $ objT c_QWidget
+  , mkBoolIsProp "dockNestingEnabled"
+    -- TODO dockOptions
+  , mkProp "documentMode" boolT
+  , mkProp "iconSize" $ objT c_QSize
+  , mkProp "menuBar" $ ptrT $ objT c_QMenuBar
+  , mkProp "menuWidget" $ ptrT $ objT c_QWidget
+  , mkProp "statusBar" $ ptrT $ objT c_QStatusBar
+    -- TODO tabShape
+    -- TODO toolButtonStyle
+  , mkProp "unifiedTitleAndToolBarOnMac" boolT
+  ]
+
+signals =
+  [ makeSignal c_QMainWindow "iconSizeChanged" c_ListenerQSize
+    -- TODO toolButtonStyleChanged
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMenu.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMenu.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMenu.hs
@@ -0,0 +1,100 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QMenu (
+  aModule,
+  c_QMenu,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_Listener, c_ListenerPtrQAction)
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Widgets.QAction (c_QAction)
+import {-# SOURCE #-} Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QMenu"] $
+  QtExport (ExportClass c_QMenu) :
+  map QtExportSignal signals
+
+c_QMenu =
+  addReqIncludes [includeStd "QMenu"] $
+  makeClass (ident "QMenu") Nothing
+  [ c_QWidget ]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithTitle" [objT c_QString]
+  , mkCtor "newWithTitleAndParent" [objT c_QString, ptrT $ objT c_QWidget]
+  ] $
+  [ mkConstMethod "actionAt" [objT c_QPoint] $ ptrT $ objT c_QAction
+  , mkConstMethod "actionGeometry" [ptrT $ objT c_QAction] $ objT c_QRect
+  , mkMethod' "addAction" "addAction" [ptrT $ objT c_QAction] voidT
+  , mkMethod' "addAction" "addNewAction" [objT c_QString] $ ptrT $ objT c_QAction
+    -- TODO addNewActionWithIcon and connecting forms
+  , mkMethod' "addMenu" "addMenu" [ptrT $ objT c_QMenu] $ ptrT $ objT c_QAction
+  , mkMethod' "addMenu" "addNewMenu" [objT c_QString] $ ptrT $ objT c_QMenu
+    -- TODO addNewMenuWithIcon
+  , mkMethod "addSeparator" [] $ ptrT $ objT c_QAction
+  , mkMethod "clear" [] voidT
+  , mkMethod' "exec" "exec" [] $ ptrT $ objT c_QAction
+  , mkMethod' "exec" "execAt" [objT c_QPoint, ptrT $ objT c_QAction] $ ptrT $ objT c_QAction
+    -- TODO Static exec
+  , mkMethod "hideTearOffMenu" [] voidT
+  , mkMethod "insertMenu" [ptrT $ objT c_QAction, ptrT $ objT c_QMenu] $ ptrT $ objT c_QAction
+  , mkMethod "insertSeparator" [ptrT $ objT c_QAction] $ ptrT $ objT c_QAction
+  , mkConstMethod "isEmpty" [] boolT
+  , mkConstMethod "isTearOffMenuVisible" [] boolT
+  , mkConstMethod "menuAction" [] $ ptrT $ objT c_QAction
+  , mkMethod' "popup" "popup" [objT c_QPoint] voidT
+  , mkMethod' "popup" "popupAction" [objT c_QPoint, ptrT $ objT c_QAction] voidT
+    -- TODO setIcon
+  ] ++
+  mkProps
+  [ mkProp "activeAction" $ ptrT $ objT c_QAction
+  , mkProp "defaultAction" $ ptrT $ objT c_QAction
+    -- TODO icon
+  , mkProp "separatorsCollapsible" boolT
+  , mkBoolIsProp "tearOffEnabled"
+  , mkProp "title" $ objT c_QString
+  ]
+
+signals =
+  [ makeSignal c_QMenu "aboutToHide" c_Listener
+  , makeSignal c_QMenu "aboutToShow" c_Listener
+  , makeSignal c_QMenu "hovered" c_ListenerPtrQAction
+  , makeSignal c_QMenu "triggered" c_ListenerPtrQAction
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMenuBar.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMenuBar.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMenuBar.hs
@@ -0,0 +1,88 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QMenuBar (
+  aModule,
+  c_QMenuBar,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (enumT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (wsWince)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_Corner)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerPtrQAction)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAction (c_QAction)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QMenu (c_QMenu)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QMenuBar"] $
+  QtExport (ExportClass c_QMenuBar) :
+  map QtExportSignal signals
+
+c_QMenuBar =
+  addReqIncludes [includeStd "QMenuBar"] $
+  makeClass (ident "QMenuBar") Nothing
+  [ c_QWidget ]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  [ mkConstMethod "actionAt" [objT c_QPoint] $ ptrT $ objT c_QAction
+  , mkConstMethod "actionGeometry" [ptrT $ objT c_QAction] $ objT c_QRect
+  , mkMethod' "addAction" "addAction" [ptrT $ objT c_QAction] voidT
+  , mkMethod' "addAction" "addNewAction" [objT c_QString] $ ptrT $ objT c_QAction
+    -- TODO addNewActionWithIcon and connecting forms
+  , mkMethod' "addMenu" "addMenu" [ptrT $ objT c_QMenu] $ ptrT $ objT c_QAction
+  , mkMethod' "addMenu" "addNewMenu" [objT c_QString] $ ptrT $ objT c_QMenu
+    -- TODO addNewMenuWithIcon
+  , mkMethod "addSeparator" [] $ ptrT $ objT c_QAction
+  , mkMethod "clear" [] voidT
+  , mkConstMethod "cornerWidget" [enumT e_Corner] $ ptrT $ objT c_QWidget
+  , mkMethod "insertMenu" [ptrT $ objT c_QAction, ptrT $ objT c_QMenu] $ ptrT $ objT c_QAction
+  , mkMethod "insertSeparator" [ptrT $ objT c_QAction] $ ptrT $ objT c_QAction
+  , mkMethod "setCornerWidget" [ptrT $ objT c_QWidget, enumT e_Corner] voidT
+  ] ++
+  (mkProps . collect)
+  [ just $ mkProp "activeAction" $ ptrT $ objT c_QAction
+  , test wsWince $ mkProp "defaultAction" $ ptrT $ objT c_QAction
+  , just $ mkBoolIsProp "defaultUp"
+  , just $ mkBoolIsProp "nativeMenuBar"
+  ]
+
+signals =
+  [ makeSignal c_QMenuBar "hovered" c_ListenerPtrQAction
+  , makeSignal c_QMenuBar "triggered" c_ListenerPtrQAction
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMessageBox.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMessageBox.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QMessageBox.hs
@@ -0,0 +1,192 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QMessageBox (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportBitspace, ExportClass, ExportEnum),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  mkStaticMethod,
+  mkStaticMethod',
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, enumT, objT, ptrT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QList (c_QListQAbstractButton)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (
+  bs_TextInteractionFlags,
+  e_TextFormat,
+  e_WindowModality,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerPtrQAbstractButton)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton (c_QAbstractButton)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QCheckBox (c_QCheckBox)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QDialog (c_QDialog)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QPushButton (c_QPushButton)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QMessageBox"] $
+  QtExport (ExportClass c_QMessageBox) :
+  map QtExportSignal signals ++
+  [ QtExport $ ExportEnum e_ButtonRole
+  , QtExport $ ExportEnum e_Icon
+  , QtExport $ ExportEnum e_StandardButton
+  , QtExport $ ExportBitspace bs_StandardButtons
+  ]
+
+c_QMessageBox =
+  addReqIncludes [includeStd "QMessageBox"] $
+  makeClass (ident "QMessageBox") Nothing [c_QDialog]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  collect
+  [ just $ mkStaticMethod "about" [ptrT $ objT c_QWidget, objT c_QString, objT c_QString] voidT
+  , just $ mkStaticMethod "aboutQt" [ptrT $ objT c_QWidget, objT c_QString] voidT
+  , test (qtVersion >= [4, 2]) $ mkMethod' "addButton" "addButton"
+    [ptrT $ objT c_QAbstractButton, enumT e_ButtonRole] voidT
+  , test (qtVersion >= [4, 2]) $ mkMethod' "addButton" "addNewButton"
+    [objT c_QString, enumT e_ButtonRole] $ ptrT $ objT c_QPushButton
+  , test (qtVersion >= [4, 2]) $ mkMethod' "addButton" "addStandardButton"
+    [enumT e_StandardButton] $ ptrT $ objT c_QPushButton
+  , test (qtVersion >= [4, 2]) $ mkConstMethod "button"
+    [enumT e_StandardButton] $ ptrT $ objT c_QAbstractButton
+  , test (qtVersion >= [4, 5]) $ mkConstMethod "buttonRole"
+    [ptrT $ objT c_QAbstractButton] $ enumT e_ButtonRole
+  , test (qtVersion >= [4, 5]) $ mkConstMethod "buttons" [] $ objT c_QListQAbstractButton
+  , test (qtVersion >= [4, 2]) $ mkConstMethod "clickedButton" [] $ ptrT $ objT c_QAbstractButton
+  , test (qtVersion >= [4, 2]) $ mkStaticMethod' "critical" "critical"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString] $ enumT e_StandardButton
+  , test (qtVersion >= [4, 2]) $ mkStaticMethod' "critical" "criticalWithButtons"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString,
+     bitspaceT bs_StandardButtons, enumT e_StandardButton] $
+    enumT e_StandardButton
+  , just $ mkConstMethod "defaultButton" [] $ ptrT $ objT c_QPushButton
+  , test (qtVersion >= [4, 2]) $ mkConstMethod "escapeButton" [] $ ptrT $ objT c_QAbstractButton
+  , test (qtVersion >= [4, 2]) $ mkStaticMethod' "information" "information"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString] $ enumT e_StandardButton
+  , test (qtVersion >= [4, 2]) $ mkStaticMethod' "information" "informationWithButtons"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString,
+     bitspaceT bs_StandardButtons, enumT e_StandardButton] $
+    enumT e_StandardButton
+    -- OMIT open
+  , test (qtVersion >= [4, 2]) $ mkStaticMethod' "question" "question"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString] $ enumT e_StandardButton
+  , test (qtVersion >= [4, 2]) $ mkStaticMethod' "question" "questionWithButtons"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString,
+     bitspaceT bs_StandardButtons, enumT e_StandardButton] $
+    enumT e_StandardButton
+  , test (qtVersion >= [4, 2]) $ mkMethod "removeButton" [ptrT $ objT c_QAbstractButton] voidT
+  , test (qtVersion >= [4, 2]) $ mkMethod' "setDefaultButton" "setDefaultButton"
+    [ptrT $ objT c_QPushButton] voidT
+  , test (qtVersion >= [4, 3]) $ mkMethod' "setDefaultButton" "setDefaultButtonStandard"
+    [enumT e_StandardButton] voidT
+  , test (qtVersion >= [4, 2]) $ mkMethod' "setEscapeButton" "setEscapeButton"
+    [ptrT $ objT c_QPushButton] voidT
+  , test (qtVersion >= [4, 3]) $ mkMethod' "setEscapeButton" "setEscapeButtonStandard"
+    [enumT e_StandardButton] voidT
+  , test (qtVersion >= [4, 2]) $ mkMethod "setWindowModality" [enumT e_WindowModality] voidT
+  , test (qtVersion >= [4, 2]) $ mkMethod "setWindowTitle" [objT c_QString] voidT
+  , test (qtVersion >= [4, 2]) $ mkConstMethod "standardButton"
+    [ptrT $ objT c_QAbstractButton] $ enumT e_StandardButton
+  , test (qtVersion >= [4, 2]) $ mkStaticMethod' "warning" "warning"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString] $ enumT e_StandardButton
+  , test (qtVersion >= [4, 2]) $ mkStaticMethod' "warning" "warningWithButtons"
+    [ptrT $ objT c_QWidget, objT c_QString, objT c_QString,
+     bitspaceT bs_StandardButtons, enumT e_StandardButton] $
+    enumT e_StandardButton
+  ] ++
+  (mkProps . collect)
+  [ test (qtVersion >= [5, 2]) $ mkProp "checkBox" $ ptrT $ objT c_QCheckBox
+  , test (qtVersion >= [4, 2]) $ mkProp "detailedText" $ objT c_QString
+  , just $ mkProp "icon" $ enumT e_Icon
+    -- TODO iconPixmap
+  , test (qtVersion >= [4, 2]) $ mkProp "informativeText" $ objT c_QString
+  , test (qtVersion >= [4, 2]) $ mkProp "standardButtons" $ bitspaceT bs_StandardButtons
+  , just $ mkProp "text" $ objT c_QString
+  , just $ mkProp "textFormat" $ enumT e_TextFormat
+  , test (qtVersion >= [5, 1]) $ mkProp "textInteractionFlags" $ bitspaceT bs_TextInteractionFlags
+  ]
+
+signals =
+  [ makeSignal c_QMessageBox "buttonClicked" c_ListenerPtrQAbstractButton
+  ]
+
+e_ButtonRole =
+  makeQtEnum (ident1 "QMessageBox" "ButtonRole") [includeStd "QMessageBox"]
+  [ (-1, ["invalid", "role"])
+  , (0, ["accept", "role"])
+  , (1, ["reject", "role"])
+  , (2, ["descructive", "role"])
+  , (3, ["action", "role"])
+  , (4, ["help", "role"])
+  , (5, ["yes", "role"])
+  , (6, ["no", "role"])
+  , (7, ["apply", "role"])
+  , (8, ["reset", "role"])
+  ]
+
+e_Icon =
+  makeQtEnum (ident1 "QMessageBox" "Icon") [includeStd "QMessageBox"]
+  [ (0, ["no", "icon"])
+  , (1, ["information"])
+  , (2, ["warning"])
+  , (3, ["critical"])
+  , (4, ["question"])
+  ]
+
+(e_StandardButton, bs_StandardButtons) =
+  makeQtEnumBitspace (ident1 "QMessageBox" "StandardButton") "StandardButtons"
+  [includeStd "QMessageBox"]
+  [ (0x00000400, ["ok"])
+  , (0x00002000, ["open"])
+  , (0x00000800, ["save"])
+  , (0x00400000, ["cancel"])
+  , (0x00200000, ["close"])
+  , (0x00800000, ["discard"])
+  , (0x02000000, ["apply"])
+  , (0x04000000, ["reset"])
+  , (0x08000000, ["restore", "defaults"])
+  , (0x01000000, ["help"])
+  , (0x00001000, ["save", "all"])
+  , (0x00004000, ["yes"])
+  , (0x00008000, ["yes", "to", "all"])
+  , (0x00010000, ["no"])
+  , (0x00020000, ["no", "to", "all"])
+  , (0x00040000, ["abort"])
+  , (0x00080000, ["retry"])
+  , (0x00100000, ["ignore"])
+  , (0x00000000, ["no", "button"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QProgressBar.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QProgressBar.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QProgressBar.hs
@@ -0,0 +1,89 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QProgressBar (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, enumT, intT, objT, ptrT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment, e_Orientation)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerInt)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QProgressBar"] $
+  QtExport (ExportClass c_QProgressBar) :
+  map QtExportSignal signals ++
+  collect
+  [ test (qtVersion >= [4, 1]) $ QtExport $ ExportEnum e_Direction
+  ]
+
+c_QProgressBar =
+  addReqIncludes [includeStd "QProgressBar"] $
+  makeClass (ident "QProgressBar") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  collect
+  [ just $ mkMethod "reset" [] voidT
+  , test (qtVersion >= [5, 0]) $ mkMethod "resetFormat" [] voidT  -- ADDED-BETWEEN 4.8 5.4
+  , just $ mkMethod "setRange" [intT, intT] voidT
+  , just $ mkConstMethod "text" [] $ objT c_QString
+  ] ++
+  (mkProps . collect)
+  [ just $ mkProp "alignment" $ bitspaceT bs_Alignment
+  , test (qtVersion >= [4, 2]) $ mkProp "format" $ objT c_QString
+  , test (qtVersion >= [4, 1]) $ mkProp "invertedAppearance" boolT
+  , just $ mkProp "maximum" intT
+  , just $ mkProp "minimum" intT
+  , test (qtVersion >= [4, 1]) $ mkProp "orientation" $ enumT e_Orientation
+  , test (qtVersion >= [4, 1]) $ mkProp "textDirection" $ enumT e_Direction
+  , just $ mkBoolIsProp "textVisible"
+  , just $ mkProp "value" intT
+  ]
+
+signals =
+  [ makeSignal c_QProgressBar "valueChanged" c_ListenerInt
+  ]
+
+-- Introduced in Qt 4.1.
+e_Direction =
+  makeQtEnum (ident1 "QProgressBar" "Direction") [includeStd "QProgressBar"]
+  [ (0, ["top", "to", "bottom"])
+  , (1, ["bottom", "to", "top"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QPushButton.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QPushButton.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QPushButton.hs
@@ -0,0 +1,66 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QPushButton (
+  aModule,
+  c_QPushButton,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton (c_QAbstractButton)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QMenu (c_QMenu)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QPushButton"]
+  [ QtExport $ ExportClass c_QPushButton ]
+
+c_QPushButton =
+  addReqIncludes [includeStd "QPushButton"] $
+  makeClass (ident "QPushButton") Nothing
+  [ c_QAbstractButton ]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithText" [objT c_QString]
+  , mkCtor "newWithTextAndParent" [objT c_QString, ptrT $ objT c_QWidget]
+    -- TODO Ctors with QIcon.
+  ] $
+  [ mkMethod "showMenu" [] voidT
+  ] ++
+  mkProps
+  [ mkProp "autoDefault" boolT
+  , mkBoolIsProp "default"
+  , mkBoolIsProp "flat"
+  , mkProp "menu" $ ptrT $ objT c_QMenu
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QRadioButton.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QRadioButton.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QRadioButton.hs
@@ -0,0 +1,51 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QRadioButton (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (objT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractButton (c_QAbstractButton)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QRadioButton"]
+  [ QtExport $ ExportClass c_QRadioButton ]
+
+c_QRadioButton =
+  addReqIncludes [includeStd "QRadioButton"] $
+  makeClass (ident "QRadioButton") Nothing [c_QAbstractButton]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithText" [objT c_QString]
+  , mkCtor "newWithTextAndParent" [objT c_QString, ptrT $ objT c_QWidget]
+  ]
+  []
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QRubberBand.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QRubberBand.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QRubberBand.hs
@@ -0,0 +1,65 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QRubberBand (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  )
+import Foreign.Hoppy.Generator.Types (enumT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QRubberBand"]
+  [ QtExport $ ExportClass c_QRubberBand
+  , QtExport $ ExportEnum e_Shape
+  ]
+
+c_QRubberBand =
+  addReqIncludes [includeStd "QRubberBand"] $
+  makeClass (ident "QRubberBand") Nothing [c_QWidget]
+  [ mkCtor "new" [enumT e_Shape]
+  , mkCtor "newWithParent" [enumT e_Shape, ptrT $ objT c_QWidget]
+  ]
+  [ mkMethod "move" [objT c_QPoint] voidT
+  , mkMethod "resize" [objT c_QSize] voidT
+  , mkMethod "setGeometry" [objT c_QRect] voidT
+  , mkConstMethod "shape" [] $ enumT e_Shape
+  ]
+
+e_Shape =
+  makeQtEnum (ident1 "QRubberBand" "Shape") [includeStd "QRubberBand"]
+  [ (0, ["line"])
+  , (1, ["rectangle"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QScrollArea.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QScrollArea.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QScrollArea.hs
@@ -0,0 +1,68 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QScrollArea (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, intT, objT, ptrT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractScrollArea (c_QAbstractScrollArea)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QScrollArea"]
+  [ QtExport $ ExportClass c_QScrollArea ]
+
+c_QScrollArea =
+  addReqIncludes [includeStd "QScrollArea"] $
+  makeClass (ident "QScrollArea") Nothing [c_QAbstractScrollArea]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  collect
+  [ just $ mkMethod' "ensureVisible" "ensureVisible" [intT, intT] voidT
+  , just $ mkMethod' "ensureVisible" "ensureVisibleWithMargins" [intT, intT, intT, intT] voidT
+  , test (qtVersion >= [4, 2]) $ mkMethod' "ensureWidgetVisible" "ensureWidgetVisible"
+    [ptrT $ objT c_QWidget] voidT
+  , test (qtVersion >= [4, 2]) $ mkMethod' "ensureWidgetVisible" "ensureWidgetVisibleWithMargins"
+    [ptrT $ objT c_QWidget, intT, intT] voidT
+  , just $ mkMethod "takeWidget" [] $ ptrT $ objT c_QWidget
+  ] ++
+  (mkProps . collect)
+  [ test (qtVersion >= [4, 2]) $ mkProp "alignment" $ bitspaceT bs_Alignment
+  , just $ mkProp "widget" $ ptrT $ objT c_QWidget
+  , just $ mkProp "widgetResizable" boolT
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QScrollBar.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QScrollBar.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QScrollBar.hs
@@ -0,0 +1,51 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QScrollBar (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (enumT, objT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_Orientation)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSlider (c_QAbstractSlider)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QScrollBar"]
+  [ QtExport $ ExportClass c_QScrollBar ]
+
+c_QScrollBar =
+  addReqIncludes [includeStd "QScrollBar"] $
+  makeClass (ident "QScrollBar") Nothing [c_QAbstractSlider]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithOrientation" [enumT e_Orientation]
+  , mkCtor "newWithOrientationAndParent" [enumT e_Orientation, ptrT $ objT c_QWidget]
+  ]
+  []
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QSlider.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QSlider.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QSlider.hs
@@ -0,0 +1,72 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QSlider (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass, ExportEnum),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkCtor,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (enumT, intT, objT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_Orientation)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSlider (c_QAbstractSlider)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QSlider"]
+  [ QtExport $ ExportClass c_QSlider
+  , QtExport $ ExportEnum e_TickPosition
+  ]
+
+c_QSlider =
+  addReqIncludes [includeStd "QSlider"] $
+  makeClass (ident "QSlider") Nothing [c_QAbstractSlider]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithOrientation" [enumT e_Orientation]
+  , mkCtor "newWithOrientationAndParent" [enumT e_Orientation, ptrT $ objT c_QWidget]
+  ] $
+  mkProps
+  [ mkProp "tickInterval" intT
+  , mkProp "tickPosition" $ enumT e_TickPosition
+  ]
+
+e_TickPosition =
+  makeQtEnum (ident1 "QSlider" "TickPosition") [includeStd "QSlider"]
+  [ (0, ["no", "ticks"])
+  , (1, ["ticks", "both", "sides"])
+  , (2, ["ticks", "above"])
+  , (3, ["ticks", "below"])
+    -- TicksLeft = TicksAbove
+    -- TicksRight = TicksBelow
+    --
+    -- We can't include these because duplicate enum values cause problems with
+    -- Hoppy.
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QSpinBox.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QSpinBox.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QSpinBox.hs
@@ -0,0 +1,77 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QSpinBox (
+  aModule,
+  c_QSpinBox,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Listener (
+  c_ListenerInt,
+  c_ListenerQString,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractSpinBox (c_QAbstractSpinBox)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QSpinBox"] $
+  QtExport (ExportClass c_QSpinBox) :
+  map QtExportSignal signals
+
+c_QSpinBox =
+  addReqIncludes [includeStd "QSpinBox"] $
+  makeClass (ident "QSpinBox") Nothing [c_QAbstractSpinBox]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  [ mkConstMethod "cleanText" [] $ objT c_QString
+  , mkMethod "setRange" [intT, intT] voidT
+  ] ++
+  (mkProps . collect)
+  [ test (qtVersion >= [5, 2]) $ mkProp "displayIntegerBase" intT
+  , just $ mkProp "maximum" intT
+  , just $ mkProp "minimum" intT
+  , just $ mkProp "prefix" $ objT c_QString
+  , just $ mkProp "singleStep" intT
+  , just $ mkProp "suffix" $ objT c_QString
+  , just $ mkProp "value" intT
+  ]
+
+signals =
+  [ makeSignal' c_QSpinBox "valueChanged" "valueChangedInt" c_ListenerInt
+  , makeSignal' c_QSpinBox "valueChanged" "valueChangedString" c_ListenerQString
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QSplitter.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QSplitter.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QSplitter.hs
@@ -0,0 +1,82 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QSplitter (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QList (c_QListInt)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_Orientation)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerIntInt)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QFrame (c_QFrame)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QSplitter"] $
+  [ QtExport $ ExportClass c_QSplitter
+  ] ++ map QtExportSignal signals
+
+c_QSplitter =
+  addReqIncludes [includeStd "QSplitter"] $
+  makeClass (ident "QSplitter") Nothing [c_QFrame]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithOrientation" [enumT e_Orientation]
+  , mkCtor "newWithOrientationAndParent" [enumT e_Orientation, ptrT $ objT c_QWidget]
+  ] $
+  [ mkMethod "addWidget" [ptrT $ objT c_QWidget] voidT
+  , mkConstMethod "count" [] intT
+    -- TODO getRange
+    -- TODO handle
+  , mkConstMethod "indexOf" [ptrT $ objT c_QWidget] intT
+  , mkMethod "insertWidget" [intT, ptrT $ objT c_QWidget] voidT
+  , mkConstMethod "isCollapsible" [intT] boolT
+  , mkMethod "refresh" [] voidT
+    -- TODO restoreState
+    -- TODO saveState
+  , mkMethod "setCollapsible" [intT, boolT] voidT
+  , mkMethod "setSizes" [objT c_QListInt] voidT
+  , mkMethod "setStretchFactor" [intT, intT] voidT
+  , mkMethod "sizes" [] $ objT c_QListInt
+  , mkConstMethod "widget" [intT] $ ptrT $ objT c_QWidget
+  ] ++
+  mkProps
+  [ mkProp "childrenCollapsible" boolT
+  , mkProp "handleWidth" intT
+  , mkProp "opaqueResize" boolT
+  , mkProp "orientation" $ enumT e_Orientation
+  ]
+
+signals =
+  [ makeSignal c_QSplitter "splitterMoved" c_ListenerIntInt ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QStackedLayout.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QStackedLayout.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QStackedLayout.hs
@@ -0,0 +1,84 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QStackedLayout (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass, ExportEnum),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (enumT, intT, objT, ptrT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerInt)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QLayout (c_QLayout)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QStackedLayout"] $
+  collect $
+  concat
+  [ [ just $ QtExport $ ExportClass c_QStackedLayout
+    ]
+  , map (just . QtExportSignal) signals
+  , [ test (qtVersion >= [4, 4]) $ QtExport $ ExportEnum e_StackingMode
+    ]
+  ]
+
+c_QStackedLayout =
+  addReqIncludes [includeStd "QStackedLayout"] $
+  makeClass (ident "QStackedLayout") Nothing [c_QLayout]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithLayout" [ptrT $ objT c_QLayout]
+  ] $
+  [ mkMethod "addWidget" [ptrT $ objT c_QWidget] intT
+  , mkConstMethod "count" [] intT
+  , mkMethod "insertWidget" [intT, ptrT $ objT c_QWidget] intT
+  , mkConstMethod "widget" [intT] $ ptrT $ objT c_QWidget
+  ] ++
+  (mkProps . collect)
+  [ just $ mkProp "currentIndex" intT
+  , just $ mkProp "currentWidget" $ ptrT $ objT c_QWidget
+  , test (qtVersion >= [4, 4]) $ mkProp "stackingMode" $ enumT e_StackingMode
+  ]
+
+signals =
+  [ makeSignal c_QStackedLayout "currentChanged" c_ListenerInt
+  , makeSignal c_QStackedLayout "widgetRemoved" c_ListenerInt
+  ]
+
+e_StackingMode =
+  makeQtEnum (ident1 "QStackedLayout" "StackingMode") [includeStd "QStackedLayout"]
+  [ (0, ["stack", "one"])
+  , (1, ["stack", "all"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QStackedWidget.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QStackedWidget.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QStackedWidget.hs
@@ -0,0 +1,69 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QStackedWidget (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerInt)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QFrame (c_QFrame)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QStackedWidget"] $
+  QtExport (ExportClass c_QStackedWidget) :
+  map QtExportSignal signals
+
+c_QStackedWidget =
+  addReqIncludes [includeStd "QStackedWidget"] $
+  makeClass (ident "QStackedWidget") Nothing [c_QFrame]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  [ mkMethod "addWidget" [ptrT $ objT c_QWidget] intT
+  , mkConstMethod "count" [] intT
+  , mkConstMethod "indexOf" [ptrT $ objT c_QWidget] intT
+  , mkMethod "insertWidget" [intT, ptrT $ objT c_QWidget] intT
+  , mkMethod "removeWidget" [ptrT $ objT c_QWidget] voidT
+  , mkConstMethod "widget" [intT] $ ptrT $ objT c_QWidget
+  ] ++
+  mkProps
+  [ mkProp "currentIndex" intT
+  , mkProp "currentWidget" $ ptrT $ objT c_QWidget
+  ]
+
+signals =
+  [ makeSignal c_QStackedWidget "currentChanged" c_ListenerInt
+  , makeSignal c_QStackedWidget "widgetRemoved" c_ListenerInt
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QStatusBar.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QStatusBar.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QStatusBar.hs
@@ -0,0 +1,78 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QStatusBar (
+  aModule,
+  c_QStatusBar,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerQString)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QStatusBar"] $
+  QtExport (ExportClass c_QStatusBar) :
+  map QtExportSignal signals
+
+c_QStatusBar =
+  addReqIncludes [includeStd "QStatusBar"] $
+  makeClass (ident "QStatusBar") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  [ mkMethod' "addPermanentWidget" "addPermanentWidget" [ptrT $ objT c_QWidget] voidT
+  , mkMethod' "addPermanentWidget" "addPermanentWidgetWithStretch"
+    [ptrT $ objT c_QWidget, intT] voidT
+  , mkMethod' "addWidget" "addWidget" [ptrT $ objT c_QWidget] voidT
+  , mkMethod' "addWidget" "addWidgetWithStretch" [ptrT $ objT c_QWidget, intT] voidT
+  , mkMethod "clearMessage" [] voidT
+  , mkConstMethod "currentMessage" [] $ objT c_QString
+  , mkMethod' "insertPermanentWidget" "insertPermanentWidget" [intT, ptrT $ objT c_QWidget] voidT
+  , mkMethod' "insertPermanentWidget" "insertPermanentWidgetWithStretch"
+    [intT, ptrT $ objT c_QWidget, intT] voidT
+  , mkMethod' "insertWidget" "insertWidget" [intT, ptrT $ objT c_QWidget] voidT
+  , mkMethod' "insertWidget" "insertWidgetWithStretch" [intT, ptrT $ objT c_QWidget, intT] voidT
+  , mkMethod "removeWidget" [ptrT $ objT c_QWidget] voidT
+  , mkMethod' "showMessage" "showMessage" [objT c_QString] voidT
+  , mkMethod' "showMessage" "showMessageWithTimeout" [objT c_QString, intT] voidT
+  ] ++
+  mkProps
+  [ mkBoolIsProp "sizeGripEnabled"
+  ]
+
+signals =
+  [ makeSignal c_QStatusBar "messageChanged" c_ListenerQString
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QTabWidget.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QTabWidget.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QTabWidget.hs
@@ -0,0 +1,120 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QTabWidget (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass, ExportEnum),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkConstMethod,
+  mkCtor,
+  mkMethod,
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (boolT, enumT, intT, objT, ptrT, voidT)
+import Foreign.Hoppy.Generator.Version (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (e_Corner, e_TextElideMode)
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerInt)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QTabWidget"] $
+  QtExport (ExportClass c_QTabWidget) :
+  map QtExportSignal signals ++
+  [ QtExport $ ExportEnum e_TabPosition
+  , QtExport $ ExportEnum e_TabShape
+  ]
+
+c_QTabWidget =
+  addReqIncludes [includeStd "QTabWidget"] $
+  makeClass (ident "QTabWidget") Nothing [c_QWidget]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  collect
+  [ just $ mkMethod "addTab" [ptrT $ objT c_QWidget, objT c_QString] intT
+    -- TODO addTabWithIcon
+  , just $ mkMethod "clear" [] voidT
+  , just $ mkConstMethod "cornerWidget" [enumT e_Corner] $ ptrT $ objT c_QWidget
+  , just $ mkConstMethod "count" [] intT
+  , just $ mkConstMethod "indexOf" [ptrT $ objT c_QWidget] intT
+  , just $ mkMethod "insertTab" [intT, ptrT $ objT c_QWidget, objT c_QString] intT
+    -- TODO insertTabWithIcon
+  , just $ mkConstMethod "isTabEnabled" [intT] boolT
+  , just $ mkMethod "removeTab" [intT] voidT
+  , just $ mkMethod "setCornerWidget" [ptrT $ objT c_QWidget, enumT e_Corner] voidT
+  , just $ mkMethod "setTabEnabled" [intT, boolT] voidT
+    -- TODO setTabIcon
+  , just $ mkMethod "setTabText" [intT, objT c_QString] voidT
+  , just $ mkMethod "setTabToolTip" [intT, objT c_QString] voidT
+  , test (qtVersion >= [4, 1]) $ mkMethod "setTabWhatsThis" [intT, objT c_QString] voidT
+    -- TODO tabBar
+    -- TODO tabIcon
+  , just $ mkConstMethod "tabText" [intT] $ objT c_QString
+  , just $ mkConstMethod "tabToolTip" [intT] $ objT c_QString
+  , just $ mkConstMethod "tabWhatsThis" [intT] $ objT c_QString
+  , just $ mkConstMethod "widget" [intT] $ ptrT $ objT c_QWidget
+  ] ++
+  (mkProps . collect)
+  [ just $ mkProp "currentIndex" intT
+  , just $ mkProp "currentWidget" $ ptrT $ objT c_QWidget
+  , test (qtVersion >= [4, 5]) $ mkProp "documentMode" boolT
+  , test (qtVersion >= [4, 2]) $ mkProp "elideMode" $ enumT e_TextElideMode
+  , test (qtVersion >= [4, 2]) $ mkProp "iconSize" $ objT c_QSize
+  , test (qtVersion >= [4, 5]) $ mkBoolIsProp "movable"
+  , test (qtVersion >= [5, 4]) $ mkProp "tabBarAutoHide" boolT
+  , just $ mkProp "tabPosition" $ enumT e_TabPosition
+  , just $ mkProp "tabShape" $ enumT e_TabShape
+  , test (qtVersion >= [4, 5]) $ mkProp "tabsClosable" boolT
+  , test (qtVersion >= [4, 2]) $ mkProp "usesScrollButtons" boolT
+  ]
+
+e_TabPosition =
+  makeQtEnum (ident1 "QTabWidget" "TabPosition") [includeStd "QTabWidget"]
+  [ (0, ["north"])
+  , (1, ["south"])
+  , (2, ["west"])
+  , (3, ["east"])
+  ]
+
+e_TabShape =
+  makeQtEnum (ident1 "QTabWidget" "TabShape") [includeStd "QTabWidget"]
+  [ (0, ["rounded"])
+  , (1, ["triangular"])
+  ]
+
+signals =
+  [ makeSignal c_QTabWidget "currentChanged" c_ListenerInt
+  , makeSignal c_QTabWidget "tabBarClicked" c_ListenerInt
+  , makeSignal c_QTabWidget "tabBarDoubleClicked" c_ListenerInt
+  , makeSignal c_QTabWidget "tabCloseRequested" c_ListenerInt
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QTextEdit.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QTextEdit.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QTextEdit.hs
@@ -0,0 +1,151 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QTextEdit (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportEnum, ExportClass),
+  addReqIncludes,
+  ident,
+  ident1,
+  includeStd,
+  makeClass,
+  mkBoolIsProp,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, enumT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (bs_Alignment, qreal)
+import Graphics.UI.Qtah.Generator.Interface.Gui.QColor (c_QColor)
+import Graphics.UI.Qtah.Generator.Interface.Listener (
+  c_Listener,
+  c_ListenerBool,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAbstractScrollArea (c_QAbstractScrollArea)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QMenu (c_QMenu)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QTextEdit"] $
+  QtExport (ExportClass c_QTextEdit) :
+  map QtExportSignal signals ++
+  [ QtExport $ ExportEnum e_LineWrapMode ]
+
+c_QTextEdit =
+  addReqIncludes [includeStd "QTextEdit"] $
+  makeClass (ident "QTextEdit") Nothing [c_QAbstractScrollArea]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  , mkCtor "newWithText" [objT c_QString]
+  , mkCtor "newWithTextAndParent" [objT c_QString, ptrT $ objT c_QWidget]
+  ] $
+  [ mkConstMethod "anchorAt" [objT c_QPoint] $ objT c_QString
+  , mkMethod "append" [objT c_QString] voidT
+  , mkConstMethod "canPaste" [] boolT
+  , mkMethod "clear" [] voidT
+  , mkMethod "copy" [] voidT
+  , mkMethod' "createStandardContextMenu" "createStandardContextMenu" [] $ ptrT $ objT c_QMenu
+  , mkMethod' "createStandardContextMenu" "createStandardContextMenuAt" [objT c_QPoint] $
+    ptrT $ objT c_QMenu
+    -- TODO cursorForPosition
+  , mkConstMethod' "cursorRect" "cursorRect" [] $ objT c_QRect
+    -- TODO cursorRect(const QTextCursor&)
+  , mkMethod "cut" [] voidT
+  , mkMethod "ensureCursorVisible" [] voidT
+  , mkMethod' "find" "find" [objT c_QString] boolT
+    -- TODO find with FindFlags
+  , mkMethod "insertHtml" [objT c_QString] voidT
+  , mkMethod "insertPlainText" [objT c_QString] voidT
+    -- TODO loadResource
+    -- TODO mergeCurrentCharFormat
+    -- TODO moveCursor
+  , mkMethod "paste" [] voidT
+    -- TODO print
+  , mkMethod "redo" [] voidT
+  , mkMethod "scrollToAnchor" [objT c_QString] voidT
+  , mkMethod "selectAll" [] voidT
+  , mkMethod "setHtml" [objT c_QString] voidT
+  , mkMethod "setPlainText" [objT c_QString] voidT
+  , mkMethod "setText" [objT c_QString] voidT
+  , mkConstMethod "toHtml" [] $ objT c_QString
+  , mkConstMethod "toPlainText" [] $ objT c_QString
+  , mkMethod "undo" [] voidT
+  , mkMethod "zoomIn" [] voidT
+  , mkMethod' "zoomIn" "zoomInPoints" [intT] voidT
+  , mkMethod "zoomOut" [] voidT
+  , mkMethod' "zoomOut" "zoomOutPoints" [intT] voidT
+  ] ++
+  mkProps
+  [ mkProp "acceptRichText" boolT
+  , mkProp "alignment" $ bitspaceT bs_Alignment
+    -- TODO autoFormatting
+    -- TODO currentCharFormat
+    -- TODO currentFont
+  , mkProp "cursorWidth" intT
+    -- TODO document
+  , mkProp "documentTitle" $ objT c_QString
+    -- TODO extraSelections
+  , mkProp "fontFamily" $ objT c_QString
+  , mkProp "fontItalic" boolT
+  , mkProp "fontPointSize" qreal
+  , mkProp "fontUnderline" boolT
+  , mkProp "fontWeight" intT
+  , mkProp "lineWrapColumnOrWidth" intT
+  , mkProp "lineWrapMode" $ enumT e_LineWrapMode
+  , mkProp "overwriteMode" boolT
+  , mkBoolIsProp "readOnly"
+  , mkProp "tabChangesFocus" boolT
+  , mkProp "tabStopWidth" intT
+  , mkProp "textBackgroundColor" $ objT c_QColor
+  , mkProp "textColor" $ objT c_QColor
+    -- TODO textCursor
+    -- TODO textInteractionFlags
+  , mkBoolIsProp "undoRedoEnabled"
+    -- TODO wordWrapMode
+  ]
+
+signals =
+  [ makeSignal c_QTextEdit "copyAvailable" c_ListenerBool
+    -- TODO currentCharFormatChanged
+  , makeSignal c_QTextEdit "cursorPositionChanged" c_Listener
+  , makeSignal c_QTextEdit "redoAvailable" c_ListenerBool
+  , makeSignal c_QTextEdit "selectionChanged" c_Listener
+  , makeSignal c_QTextEdit "textChanged" c_Listener
+  , makeSignal c_QTextEdit "undoAvailable" c_ListenerBool
+  ]
+
+e_LineWrapMode =
+  makeQtEnum (ident1 "QTextEdit" "LineWrapMode") [includeStd "QTextEdit"]
+  [ (0, ["no", "wrap"])
+  , (1, ["widget", "width"])
+  , (2, ["fixed", "pixel", "width"])
+  , (3, ["fixed", "column", "width"])
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QVBoxLayout.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QVBoxLayout.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QVBoxLayout.hs
@@ -0,0 +1,48 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QVBoxLayout (
+  aModule,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkCtor,
+  )
+import Foreign.Hoppy.Generator.Types (objT, ptrT)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QBoxLayout (c_QBoxLayout)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (c_QWidget)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QVBoxLayout"]
+  [ QtExport $ ExportClass c_QVBoxLayout ]
+
+c_QVBoxLayout =
+  addReqIncludes [includeStd "QVBoxLayout"] $
+  makeClass (ident "QVBoxLayout") Nothing [c_QBoxLayout]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ]
+  []
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QWidget.hs b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QWidget.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QWidget.hs
@@ -0,0 +1,313 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (
+  aModule,
+  c_QWidget,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (
+  Export (ExportClass),
+  addReqIncludes,
+  ident,
+  includeStd,
+  makeClass,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
+  mkProp,
+  mkProps,
+  mkStaticMethod,
+  )
+import Foreign.Hoppy.Generator.Types (bitspaceT, boolT, enumT, intT, objT, ptrT, voidT)
+import Graphics.UI.Qtah.Generator.Flag (collect, just, test)
+import Graphics.UI.Qtah.Generator.Flags (keypadNavigation, qdoc, qtVersion)
+import Graphics.UI.Qtah.Generator.Interface.Core.QMargins (c_QMargins)
+import Graphics.UI.Qtah.Generator.Interface.Core.QObject (c_QObject)
+import Graphics.UI.Qtah.Generator.Interface.Core.QPoint (c_QPoint)
+import Graphics.UI.Qtah.Generator.Interface.Core.QRect (c_QRect)
+import Graphics.UI.Qtah.Generator.Interface.Core.QSize (c_QSize)
+import Graphics.UI.Qtah.Generator.Interface.Core.QString (c_QString)
+import Graphics.UI.Qtah.Generator.Interface.Core.Types (
+  bs_WindowFlags,
+  bs_WindowStates,
+  e_LayoutDirection,
+  e_WindowModality,
+  e_WindowType,
+  qreal,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Listener (c_ListenerQPoint)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QAction (c_QAction)
+import Graphics.UI.Qtah.Generator.Interface.Widgets.QLayout (c_QLayout)
+import Graphics.UI.Qtah.Generator.Types
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+aModule =
+  AQtModule $
+  makeQtModule ["Widgets", "QWidget"] $
+  QtExport (ExportClass c_QWidget) :
+  map QtExportSignal signals
+
+c_QWidget =
+  addReqIncludes [includeStd "QWidget"] $
+  makeClass (ident "QWidget") Nothing
+  [ c_QObject ]
+  [ mkCtor "new" []
+  , mkCtor "newWithParent" [ptrT $ objT c_QWidget]
+  ] $
+  collect
+  [ just $ mkConstMethod "acceptDrops" [] boolT
+  , just $ mkConstMethod "accessibleDescription" [] $ objT c_QString
+  , just $ mkConstMethod "accessibleName" [] $ objT c_QString
+    -- TODO actions
+  , just $ mkMethod "activateWindow" [] voidT
+  , just $ mkMethod "addAction" [ptrT $ objT c_QAction] voidT
+    -- TODO addActions
+  , just $ mkMethod "adjustSize" [] voidT
+  , just $ mkConstMethod "autoFillBackground" [] boolT
+    -- TODO backgroundRole
+  , just $ mkConstMethod "baseSize" [] $ objT c_QSize
+  , just $ mkConstMethod' "childAt" "childAtRaw" [intT, intT] $ ptrT $ objT c_QWidget
+  , just $ mkConstMethod' "childAt" "childAtPoint" [objT c_QPoint] $ ptrT $ objT c_QWidget
+  , just $ mkConstMethod "childrenRect" [] $ objT c_QRect
+    -- TODO childrenRegion
+  , just $ mkMethod "clearFocus" [] voidT
+  , just $ mkMethod "clearMask" [] voidT
+  , just $ mkMethod "close" [] voidT
+  , just $ mkConstMethod "contentsMargins" [] $ objT c_QMargins
+  , just $ mkConstMethod "contentsRect" [] $ objT c_QRect
+    -- TODO contextMenuPolicy
+    -- TODO cursor
+    -- TODO effectiveWinId
+  , just $ mkConstMethod "ensurePolished" [] voidT
+    -- TODO find
+    -- TODO focusPolicy
+  , just $ mkConstMethod "focusProxy" [] $ ptrT $ objT c_QWidget
+  , just $ mkConstMethod "focusWidget" [] $ ptrT $ objT c_QWidget
+    -- TODO font
+    -- TODO fontInfo
+    -- TODO fontMetrics
+    -- TODO foregroundRole
+  , just $ mkConstMethod "frameGeometry" [] $ objT c_QRect
+  , just $ mkConstMethod "frameSize" [] $ objT c_QSize
+  , just $ mkConstMethod "geometry" [] $ objT c_QRect
+    -- TODO grabGesture
+  , just $ mkMethod "grabKeyboard" [] voidT
+  , just $ mkMethod "grabMouse" [] voidT
+    -- TODO grabMouse(const QCursor&)
+    -- TODO grabShortcut
+    -- TODO graphicsEffect
+    -- TODO graphicsProxyWidget
+  , test keypadNavigation $ mkConstMethod "hasEditFocus" [] boolT
+  , just $ mkConstMethod "hasFocus" [] boolT
+  , just $ mkConstMethod "hasMouseTracking" [] boolT
+  , just $ mkConstMethod "height" [] intT
+  , just $ mkConstMethod "heightForWidth" [intT] intT
+  , just $ mkMethod "hide" [] voidT
+    -- TODO inputContext
+    -- TODO inputMethodHints
+    -- TODO inputMethodQuery
+  , just $ mkMethod "insertAction" [ptrT $ objT c_QAction, ptrT $ objT c_QAction] voidT
+    -- TODO insertActions
+  , just $ mkConstMethod "isActiveWindow" [] boolT
+  , just $ mkConstMethod "isAncestorOf" [ptrT $ objT c_QWidget] boolT
+  , just $ mkConstMethod "isEnabled" [] boolT
+  , just $ mkConstMethod "isEnabledTo" [ptrT $ objT c_QWidget] boolT
+  , just $ mkConstMethod "isFullScreen" [] boolT
+  , just $ mkConstMethod "isHidden" [] boolT
+  , just $ mkConstMethod "isMaximized" [] boolT
+  , just $ mkConstMethod "isMinimized" [] boolT
+  , just $ mkConstMethod "isModal" [] boolT
+  , just $ mkConstMethod "isVisible" [] boolT
+  , just $ mkConstMethod "isVisibleTo" [ptrT $ objT c_QWidget] boolT
+  , just $ mkConstMethod "isWindow" [] boolT
+  , just $ mkConstMethod "isWindowModified" [] boolT
+  , just $ mkStaticMethod "keyboardGrabber" [] $ ptrT $ objT c_QWidget
+  , just $ mkConstMethod "layout" [] $ ptrT $ objT c_QLayout
+  , just $ mkConstMethod "layoutDirection" [] $ enumT e_LayoutDirection
+    -- TODO locale
+    -- TODO macCGHandle
+    -- TODO macQDHandle
+  , just $ mkMethod "lower" [] voidT
+  , just $ mkConstMethod "mapFrom" [ptrT $ objT c_QWidget, objT c_QPoint] $ objT c_QPoint
+  , just $ mkConstMethod "mapFromGlobal" [objT c_QPoint] $ objT c_QPoint
+  , just $ mkConstMethod "mapFromParent" [objT c_QPoint] $ objT c_QPoint
+  , just $ mkConstMethod "mapTo" [ptrT $ objT c_QWidget, objT c_QPoint] $ objT c_QPoint
+  , just $ mkConstMethod "mapToGlobal" [objT c_QPoint] $ objT c_QPoint
+  , just $ mkConstMethod "mapToParent" [objT c_QPoint] $ objT c_QPoint
+  , just $ mkConstMethod "maximumHeight" [] intT
+  , just $ mkConstMethod "maximumSize" [] $ objT c_QSize
+  , just $ mkConstMethod "maximumWidth" [] intT
+  , just $ mkConstMethod "minimumHeight" [] intT
+  , just $ mkConstMethod "minimumSize" [] $ objT c_QSize
+  , just $ mkConstMethod "minimumWidth" [] intT
+  , just $ mkStaticMethod "mouseGrabber" [] $ ptrT $ objT c_QWidget
+  , just $ mkMethod "move" [objT c_QPoint] voidT
+  , just $ mkConstMethod "nativeParentWidget" [] $ ptrT $ objT c_QWidget
+  , just $ mkConstMethod "nextInFocusChain" [] $ ptrT $ objT c_QWidget
+  , just $ mkConstMethod "normalGeometry" [] $ objT c_QRect
+    -- TODO overrideWindowFlags
+    -- TODO palette
+  , just $ mkConstMethod "parentWidget" [] $ ptrT $ objT c_QWidget
+    -- TODO platformWindow
+    -- TODO platformWindowFormat
+  , just $ mkConstMethod "pos" [] $ objT c_QPoint
+  , just $ mkConstMethod "previousInFocusChain" [] $ ptrT $ objT c_QWidget
+  , just $ mkMethod "raise" [] voidT
+  , just $ mkConstMethod "rect" [] $ objT c_QRect
+  , just $ mkMethod "releaseKeyboard" [] voidT
+  , just $ mkMethod "releaseMouse" [] voidT
+    -- TODO releaseShortcut
+  , just $ mkMethod "removeAction" [ptrT $ objT c_QAction] voidT
+    -- TODO render
+  , just $ mkMethod' "repaint" "repaint" [] voidT
+  , just $ mkMethod' "repaint" "repaintRaw" [intT, intT, intT, intT] voidT
+  , just $ mkMethod' "repaint" "repaintRect" [objT c_QRect] voidT
+    -- TODO repaint(const QRegion&)
+  , just $ mkMethod' "resize" "resize" [objT c_QSize] voidT
+  , just $ mkMethod' "resize" "resizeRaw" [intT, intT] voidT
+    -- TODO restoreGeometry
+    -- TODO saveGeometry
+  , just $ mkMethod' "scroll" "scrollRaw" [intT, intT] voidT
+  , just $ mkMethod' "scroll" "scrollRect" [intT, intT, objT c_QRect] voidT
+  , just $ mkMethod "setAcceptDrops" [boolT] voidT
+  , just $ mkMethod "setAccessibleDescription" [objT c_QString] voidT
+  , just $ mkMethod "setAccessibleName" [objT c_QString] voidT
+    -- TODO setAttribute
+  , just $ mkMethod "setAutoFillBackground" [boolT] voidT
+    -- TODO setBackgroundRole
+  , just $ mkMethod' "setBaseSize" "setBaseSize" [objT c_QSize] voidT
+  , just $ mkMethod' "setBaseSize" "setBaseSizeRaw" [intT, intT] voidT
+  , just $ mkMethod' "setContentsMargins" "setContentsMargins" [objT c_QMargins] voidT
+  , just $ mkMethod' "setContentsMargins" "setContentsMarginsRaw" [intT, intT, intT, intT] voidT
+    -- TODO setContextMenuPolicy
+  , just $ mkMethod "setEnabled" [boolT] voidT
+  , just $ mkMethod "setDisabled" [boolT] voidT
+  , test keypadNavigation $ mkMethod "setEditFocus" [boolT] voidT
+  , just $ mkMethod "setFixedHeight" [intT] voidT
+  , just $ mkMethod' "setFixedSize" "setFixedSize" [objT c_QSize] voidT
+  , just $ mkMethod' "setFixedSize" "setFixedSizeRaw" [intT, intT] voidT
+  , just $ mkMethod "setFixedWidth" [intT] voidT
+  , just $ mkMethod "setFocus" [] voidT
+    -- TODO setFocus(Qt::FocusReason)
+    -- TODO setFocusPolicy
+  , just $ mkMethod "setFocusProxy" [ptrT $ objT c_QWidget] voidT
+    -- TODO setFont
+    -- TODO setForegroundRole
+  , just $ mkMethod' "setGeometry" "setGeometryRaw" [intT, intT, intT, intT] voidT
+  , just $ mkMethod' "setGeometry" "setGeometryRect" [objT c_QRect] voidT
+    -- TODO setGraphicsEffect
+  , just $ mkMethod "setHidden" [boolT] voidT
+    -- TODO setInputContext
+    -- TODO setInputMethodHints
+  , just $ mkMethod "setLayout" [ptrT $ objT c_QLayout] voidT
+  , just $ mkMethod "setLayoutDirection" [enumT e_LayoutDirection] voidT
+    -- TODO setLocale
+    -- TODO setMask
+  , just $ mkMethod "setMaximumHeight" [intT] voidT
+  , just $ mkMethod' "setMaximumSize" "setMaximumSize" [objT c_QSize] voidT
+  , just $ mkMethod' "setMaximumSize" "setMaximumSizeRaw" [intT, intT] voidT
+  , just $ mkMethod "setMaximumWidth" [intT] voidT
+  , just $ mkMethod "setMinimumHeight" [intT] voidT
+  , just $ mkMethod' "setMinimumSize" "setMinimumSize" [objT c_QSize] voidT
+  , just $ mkMethod' "setMinimumSize" "setMinimumSizeRaw" [intT, intT] voidT
+  , just $ mkMethod "setMinimumWidth" [intT] voidT
+  , just $ mkMethod "setMouseTracking" [boolT] voidT
+    -- TODO setPalette
+  , just $ mkMethod' "setParent" "setParent" [ptrT $ objT c_QWidget] voidT
+  , just $ mkMethod' "setParent" "setParentWithFlags"
+    [ptrT $ objT c_QWidget, bitspaceT bs_WindowFlags] voidT
+    -- TODO setPlatformWindow
+    -- TODO setPlatformWindowFormat
+    -- TODO setShortcutAutoRepeat
+    -- TODO setShortcutEnabled
+  , just $ mkMethod' "setSizeIncrement" "setSizeIncrement" [objT c_QSize] voidT
+  , just $ mkMethod' "setSizeIncrement" "setSizeIncrementRaw" [intT, intT] voidT
+    -- TODO setSizePolicy
+  , just $ mkMethod "setStatusTip" [objT c_QString] voidT
+    -- TODO setStyle
+  , just $ mkMethod "setStyleSheet" [objT c_QString] voidT
+  , just $ mkStaticMethod "setTabOrder" [ptrT $ objT c_QWidget, ptrT $ objT c_QWidget] voidT
+  , just $ mkMethod "setToolTip" [objT c_QString] voidT
+  , just $ mkMethod "setUpdatesEnabled" [boolT] voidT
+  , just $ mkMethod "setVisible" [boolT] voidT
+  , just $ mkMethod "setWhatsThis" [objT c_QString] voidT
+  , just $ mkMethod "setWindowFilePath" [objT c_QString] voidT
+    -- TODO setWindowIcon
+  , just $ mkMethod "setWindowIconText" [objT c_QString] voidT
+  , just $ mkMethod "setWindowModified" [boolT] voidT
+  , just $ mkMethod "setWindowRole" [objT c_QString] voidT
+    -- TODO setWindowSurface
+  , test qdoc $ mkMethod "setupUi" [ptrT $ objT c_QWidget] voidT
+  , just $ mkMethod "show" [] voidT
+  , just $ mkMethod "showFullScreen" [] voidT
+  , just $ mkMethod "showMaximized" [] voidT
+  , just $ mkMethod "showMinimized" [] voidT
+  , just $ mkMethod "showNormal" [] voidT
+  , just $ mkConstMethod "size" [] $ objT c_QSize
+  , just $ mkConstMethod "sizeHint" [] $ objT c_QSize
+  , just $ mkConstMethod "sizeIncrement" [] $ objT c_QSize
+    -- TODO sizePolicy
+  , just $ mkMethod "stackUnder" [ptrT $ objT c_QWidget] voidT
+  , just $ mkConstMethod "statusTip" [] $ objT c_QString
+  , just $ mkConstMethod "styleSheet" [] $ objT c_QString
+    -- TODO testAttribute
+  , just $ mkConstMethod "toolTip" [] $ objT c_QString
+  , just $ mkConstMethod "underMouse" [] boolT
+    -- TODO ungrabGesture
+  , just $ mkMethod "unsetCursor" [] voidT
+  , just $ mkMethod "unsetLayoutDirection" [] voidT
+  , just $ mkMethod "unsetLocale" [] voidT
+  , just $ mkMethod' "update" "update" [] voidT
+  , just $ mkMethod' "update" "updateRaw" [intT, intT, intT, intT] voidT
+  , just $ mkMethod' "update" "updateRect" [objT c_QRect] voidT
+    -- TODO update(const QRegion&)
+  , just $ mkMethod "updateGeometry" [] voidT
+  , just $ mkConstMethod "updatesEnabled" [] boolT
+    -- TODO visibleRegion
+  , just $ mkConstMethod "whatsThis" [] $ objT c_QString
+  , just $ mkConstMethod "width" [] intT
+  , just $ mkConstMethod "window" [] $ ptrT $ objT c_QWidget
+  , just $ mkConstMethod "windowFilePath" [] $ objT c_QString
+    -- TODO windowIcon
+  , just $ mkConstMethod "windowIconText" [] $ objT c_QString
+  , just $ mkConstMethod "windowRole" [] $ objT c_QString
+    -- TODO windowSurface
+  , test (qtVersion < [5, 0]) $ mkConstMethod "windowType" [] $ enumT e_WindowType
+    -- TODO winId
+  , just $ mkConstMethod "x" [] intT
+    -- TODO x11Info
+    -- TODO x11PictureHandle
+  , just $ mkConstMethod "y" [] intT
+  ] ++
+  mkProps
+  [ mkProp "windowFlags" $ bitspaceT bs_WindowFlags
+  , mkProp "windowModality" $ enumT e_WindowModality
+  , mkProp "windowOpacity" qreal
+  , mkProp "windowState" $ bitspaceT bs_WindowStates
+  , mkProp "windowTitle" $ objT c_QString
+  ]
+
+signals =
+  [ makeSignal c_QWidget "customContextMenuRequested" c_ListenerQPoint
+    -- TODO windowIconChanged (>=5.0?)
+    -- TODO windowIconTextChanged (>=5.0?)
+    -- TODO windowTitleChanged (>=5.0?)
+  ]
diff --git a/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QWidget.hs-boot b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QWidget.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Interface/Widgets/QWidget.hs-boot
@@ -0,0 +1,24 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Interface.Widgets.QWidget (
+  c_QWidget,
+  ) where
+
+import Foreign.Hoppy.Generator.Spec (Class)
+
+c_QWidget :: Class
diff --git a/src/Graphics/UI/Qtah/Generator/Module.hs b/src/Graphics/UI/Qtah/Generator/Module.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Module.hs
@@ -0,0 +1,392 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE CPP #-}
+
+module Graphics.UI.Qtah.Generator.Module (
+  generateModule,
+  ) where
+
+import Control.Monad (forM_, unless, when)
+#if MIN_VERSION_mtl(2,2,1)
+import Control.Monad.Except (throwError)
+#else
+import Control.Monad.Error (throwError)
+#endif
+import Data.List (find, intercalate, intersperse, isPrefixOf, sort)
+import Data.Maybe (isJust)
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat)
+#endif
+import Foreign.Hoppy.Generator.Language.Cpp (execChunkWriter, sayType)
+import Foreign.Hoppy.Generator.Language.Haskell (
+  Generator,
+  HsTypeSide (HsHsSide),
+  addExport,
+  addExports,
+  addImports,
+  cppTypeToHsTypeAndUse,
+  execGenerator,
+  getClassHaskellConversion,
+  importHsModuleForExtName,
+  indent,
+  inFunction,
+  ln,
+  prettyPrint,
+  renderPartial,
+  sayLn,
+  saysLn,
+  toHsBitspaceClassName,
+  toHsBitspaceToNumName,
+  toHsBitspaceTypeName,
+  toHsBitspaceValueName,
+  toHsCastMethodName,
+  toHsDataTypeName,
+  toHsDownCastMethodName,
+  toHsEnumTypeName,
+  toHsFnName,
+  toHsPtrClassName,
+  toHsValueClassName,
+  )
+import Foreign.Hoppy.Generator.Spec (
+  Class,
+  Constness (Const, Nonconst),
+  Ctor,
+  Export (ExportBitspace, ExportCallback, ExportClass, ExportEnum, ExportFn, ExportVariable),
+  ExtName,
+  FnName (FnName),
+  Function,
+  Interface,
+  Method,
+  MethodImpl (RealMethod),
+  Type (Internal_TCallback),
+  bitspaceExtName,
+  bitspaceValueNames,
+  callbackParams,
+  classCtors,
+  classExtName,
+  classMethods,
+  ctorExtName,
+  ctorParams,
+  enumExtName,
+  fnExtName,
+  fromExtName,
+  getClassyExtName,
+  hsImport1,
+  hsImports,
+  methodExtName,
+  methodImpl,
+  toExtName,
+  varExtName,
+  varGetterExtName,
+  varIsConst,
+  varSetterExtName,
+  )
+import Foreign.Hoppy.Generator.Types (objT)
+import Graphics.UI.Qtah.Generator.Flags (qrealFloat)
+import Graphics.UI.Qtah.Generator.Common (fromMaybeM, writeFileIfDifferent)
+import Graphics.UI.Qtah.Generator.Types (
+  QtExport (QtExport, QtExportEvent, QtExportFnRenamed, QtExportSignal, QtExportSpecials),
+  QtModule,
+  Signal,
+  moduleNameAppend,
+  qtModulePath,
+  qtModuleQtExports,
+  signalClass,
+  signalCName,
+  signalHaskellName,
+  signalListenerClass,
+  )
+import Graphics.UI.Qtah.Generator.Interface.Imports
+import Language.Haskell.Syntax (
+  HsName (HsIdent),
+  HsQName (UnQual),
+  HsQualType (HsQualType),
+  HsType (HsTyApp, HsTyCon, HsTyFun, HsTyVar),
+  )
+import System.Directory (createDirectoryIfMissing)
+import System.Exit (exitFailure)
+import System.FilePath ((</>), (<.>), pathSeparator, takeDirectory)
+
+generateModule :: Interface -> FilePath -> String -> QtModule -> IO ()
+generateModule iface srcDir baseModuleName qtModule = do
+  let fullModuleName = moduleNameAppend baseModuleName $ intercalate "." $ qtModulePath qtModule
+      qtExports = qtModuleQtExports qtModule
+
+  let generation =
+        fmap (("{-# LANGUAGE NoMonomorphismRestriction #-}\n\n" ++) . renderPartial) $
+        execGenerator iface fullModuleName $ do
+          -- As in generated Hoppy bindings, avoid non-qualified Prelude uses in
+          -- generated code here.
+          addImports $ hsImports "Prelude" []
+
+          -- Generate bindings for all of the exports.
+          mapM_ (sayQtExport $ qtModulePath qtModule) qtExports
+
+  case generation of
+    Left errorMsg -> do
+      putStrLn $ "Error generating Qt modules: " ++ errorMsg
+      exitFailure
+    Right source -> do
+      let path =
+            srcDir </>
+            map (\c -> if c == '.' then pathSeparator else c) fullModuleName <.>
+            "hs"
+      createDirectoryIfMissing True $ takeDirectory path
+      writeFileIfDifferent path source
+
+getFnReexportName :: Function -> String
+getFnReexportName = getFnImportName
+
+classUpCastReexportName :: String
+classUpCastReexportName = "cast"
+
+classUpCastConstReexportName :: String
+classUpCastConstReexportName = "castConst"
+
+classDownCastReexportName :: String
+classDownCastReexportName = "downCast"
+
+classDownCastConstReexportName :: String
+classDownCastConstReexportName = "downCastConst"
+
+classEncodeReexportName :: String
+classEncodeReexportName = "encode"
+
+classDecodeReexportName :: String
+classDecodeReexportName = "decode"
+
+getCtorReexportName :: Class -> Ctor -> String
+getCtorReexportName cls = toBindingNameWithoutClassPrefix cls . ctorExtName
+
+getMethodReexportName :: Class -> Method -> String
+getMethodReexportName cls = toBindingNameWithoutClassPrefix cls . methodExtName
+
+-- | Qtah uses @ClassName_innerName@ 'ExtName's for things in classes.  This
+-- function strips the @ClassName_@ prefix off of an 'ExtName', if present, and
+-- converts it to a function name.
+toBindingNameWithoutClassPrefix :: Class -> ExtName -> String
+toBindingNameWithoutClassPrefix cls name =
+  toHsFnName $ toExtName $
+  dropPrefix (fromExtName (classExtName cls) ++ "_") $
+  fromExtName name
+
+-- | @dropPrefix prefix str@ strips @prefix@ from @str@ if @str@ starts with
+-- @prefix@, and returns @str@ unmodified otherwise.
+dropPrefix :: String -> String -> String
+dropPrefix prefix str =
+  if prefix `isPrefixOf` str
+  then drop (length prefix) str
+  else str
+
+getFnImportName :: Function -> String
+getFnImportName = toHsFnName . fnExtName
+
+sayClassEncodingFnReexports :: Class -> Generator ()
+sayClassEncodingFnReexports cls = inFunction "sayClassEncodingFnReexports" $
+  when (classIsConvertible cls) $ do
+    -- Generated encode and decode functions require some things from Hoppy
+    -- support and the Prelude.
+    addImports $ mconcat [importForPrelude, importForRuntime]
+
+    hsHsType <- cppTypeToHsTypeAndUse HsHsSide (objT cls)
+    let constPtrClassName = toHsPtrClassName Const cls
+        dataTypeName = toHsDataTypeName Nonconst cls
+        ptrHsType = HsTyCon $ UnQual $ HsIdent dataTypeName
+        thisTyVar = HsTyVar $ HsIdent "this"
+        encodeFnType = HsTyFun hsHsType $ HsTyApp (HsTyCon $ UnQual $ HsIdent "QtahP.IO") ptrHsType
+        decodeFnType = HsQualType [(UnQual $ HsIdent constPtrClassName, [thisTyVar])] $
+                       HsTyFun thisTyVar $
+                       HsTyApp (HsTyCon $ UnQual $ HsIdent "QtahP.IO") hsHsType
+    ln
+    saysLn [classEncodeReexportName, " :: ", prettyPrint encodeFnType]
+    saysLn [classEncodeReexportName, " = QtahFHR.encodeAs (QtahP.undefined :: ", dataTypeName, ")"]
+    ln
+    saysLn [classDecodeReexportName, " :: ", prettyPrint decodeFnType]
+    saysLn [classDecodeReexportName, " = QtahFHR.decode QtahP.. ", toHsCastMethodName Const cls]
+
+sayQtExport :: [String] -> QtExport -> Generator ()
+sayQtExport path qtExport = case qtExport of
+  QtExport (ExportVariable v) -> do
+    importHsModuleForExtName $ varExtName v
+    addExport $ toHsFnName $ varGetterExtName v
+    unless (varIsConst v) $ addExport $ toHsFnName $ varSetterExtName v
+
+  QtExport (ExportEnum e) -> do
+    importHsModuleForExtName $ enumExtName e
+    let spec = toHsEnumTypeName e ++ " (..)"
+    addExport spec
+
+  QtExport (ExportBitspace b) -> do
+    importHsModuleForExtName $ bitspaceExtName b
+    addExport $ toHsBitspaceTypeName b
+    addExport $ toHsBitspaceToNumName b
+    addExport $ toHsBitspaceClassName b ++ " (..)"
+    forM_ (bitspaceValueNames b) $ \(_, valueName) ->
+      addExport $ toHsBitspaceValueName b valueName
+
+  QtExport (ExportFn fn) -> do
+    importHsModuleForExtName $ fnExtName fn
+    addExport $ getFnReexportName fn
+
+  QtExportFnRenamed fn rename -> do
+    importHsModuleForExtName $ fnExtName fn
+    addExport rename
+    sayBind rename $ getFnImportName fn
+
+  QtExport (ExportCallback _) -> return ()
+
+  QtExport (ExportClass cls) -> sayExportClass cls
+
+  QtExportSignal sig -> sayExportSignal sig
+
+  QtExportEvent cls -> do
+    sayExportClass cls
+
+    let typeName = toHsDataTypeName Nonconst cls
+    addImports $ mconcat [hsImport1 "Prelude" "($)",
+                          importForEvent]
+    ln
+    saysLn ["instance QtahEvent.Event ", typeName, " where"]
+    indent $ do
+      sayLn "onEvent receiver' handler' = QtahEvent.onAnyEvent receiver' $ \\_ qevent' ->"
+      indent $
+        if path == ["Core", "QEvent"]
+        then sayLn "handler' qevent'"
+        else do
+          addImports $ mconcat [hsImport1 "Prelude" "(==)",
+                                importForPrelude,
+                                importForRuntime]
+          saysLn ["let event' = ", classDownCastReexportName, " qevent'"]
+          sayLn "in if event' == QtahFHR.nullptr then QtahP.return QtahP.False else handler' event'"
+
+  QtExportSpecials -> do
+    -- Generate a type synonym for qreal.
+    addImports importForPrelude
+    addExport "QReal"
+    ln
+    saysLn ["type QReal = ", if qrealFloat then "QtahP.Float" else "QtahP.Double"]
+
+sayExportClass :: Class -> Generator ()
+sayExportClass cls = do
+  importHsModuleForExtName $ classExtName cls
+  addExports $
+    (toHsValueClassName cls ++ " (..)") :
+    (toHsPtrClassName Const cls ++ " (..)") :
+    (toHsPtrClassName Nonconst cls ++ " (..)") :
+    toHsDataTypeName Const cls :
+    toHsDataTypeName Nonconst cls :
+    classUpCastConstReexportName :
+    classUpCastReexportName :
+    classDownCastConstReexportName :
+    classDownCastReexportName :
+    concat [ if classIsConvertible cls
+             then [classEncodeReexportName, classDecodeReexportName]
+             else []
+           , sort $ map (getCtorReexportName cls) $ classCtors cls
+           , sort $ map (getMethodReexportName cls) $ classMethods cls
+           ]
+
+  ln
+  sayBind classUpCastConstReexportName $ toHsCastMethodName Const cls
+  sayBind classUpCastReexportName $ toHsCastMethodName Nonconst cls
+  sayBind classDownCastConstReexportName $ toHsDownCastMethodName Const cls
+  sayBind classDownCastReexportName $ toHsDownCastMethodName Nonconst cls
+  sayClassEncodingFnReexports cls
+  forM_ (classCtors cls) $ \ctor ->
+    sayBind (getCtorReexportName cls ctor) $ toHsFnName $ getClassyExtName cls ctor
+  forM_ (classMethods cls) $ \method ->
+    sayBind (getMethodReexportName cls method) $ toHsFnName $ getClassyExtName cls method
+
+-- | Generates and exports a @Signal@ definition.  We create the signal from
+-- scratch in this module, rather than reexporting it from somewhere else.
+sayExportSignal :: Signal -> Generator ()
+sayExportSignal signal = inFunction "sayExportSignal" $ do
+  addImports importForSignal
+
+  let name = signalCName signal
+      cls = signalClass signal
+      ptrClassName = toHsPtrClassName Nonconst cls
+      varName = toSignalBindingName signal
+  addExport varName
+
+  let listenerClass = signalListenerClass signal
+  importHsModuleForExtName $ classExtName listenerClass
+  -- Find the listener constructor that only takes a callback.
+  listenerCtor <-
+    fromMaybeM (throwError $ concat
+                ["Couldn't find an appropriate ",
+                show (fromExtName $ classExtName listenerClass),
+                " constructor for signal ", show name]) $
+    flip find (classCtors listenerClass) $ \ctor -> case ctorParams ctor of
+      [Internal_TCallback {}] -> True
+      _ -> False
+  let [callbackType@(Internal_TCallback callback)] = ctorParams listenerCtor
+      paramTypes = callbackParams callback
+
+  -- Also find the 'connectListener' method.
+  listenerConnectMethod <-
+    fromMaybeM (throwError $ concat
+                ["Couldn't find the connectListener method in ",
+                 show listenerClass, " for signal ", show name]) $
+    find ((RealMethod (FnName "connectListener") ==) . methodImpl) $ classMethods listenerClass
+
+  callbackHsType <- cppTypeToHsTypeAndUse HsHsSide callbackType
+
+  let varType = HsQualType [(UnQual $ HsIdent ptrClassName, [HsTyVar $ HsIdent "object"])] $
+                HsTyApp (HsTyApp (HsTyCon $ UnQual $ HsIdent "QtahSignal.Signal") $
+                         HsTyVar $ HsIdent "object")
+                callbackHsType
+      internalName = concat
+                     [ fromExtName $ classExtName cls
+                     , "::"
+                     , name
+                     , " ("
+                     , fromExtName $ classExtName listenerClass
+                     , ")"
+                     ]
+  ln
+  saysLn [varName, " :: ", prettyPrint varType]
+  saysLn [varName, " = QtahSignal.Signal"]
+  indent $ do
+    sayLn "{ QtahSignal.internalConnectSignal = \\object' fn' -> do"
+    indent $ do
+      saysLn ["listener' <- ", toHsFnName $ getClassyExtName listenerClass listenerCtor, " fn'"]
+      saysLn [toHsFnName $ getClassyExtName listenerClass listenerConnectMethod,
+              " listener' object' ", show (toSignalConnectName signal paramTypes)]
+    saysLn [", QtahSignal.internalName = ", show internalName]
+    sayLn "}"
+
+sayBind :: String -> String -> Generator ()
+sayBind name value = saysLn [name, " = ", value]
+
+toSignalBindingName :: Signal -> String
+toSignalBindingName = (++ "Signal") . signalHaskellName
+
+toSignalConnectName :: Signal -> [Type] -> String
+toSignalConnectName signal paramTypes =
+  concat $
+  "2" :  -- This is a magic code added by the SIGNAL() macro.
+  signalCName signal :
+  "(" :
+  intersperse "," (map (execChunkWriter . sayType Nothing) paramTypes) ++
+  [")"]
+
+-- | Returns true iff a given class is convertible to/from a Haskell
+-- type with @encode@ and @decode@.
+classIsConvertible :: Class -> Bool
+classIsConvertible = isJust . getClassHaskellConversion
diff --git a/src/Graphics/UI/Qtah/Generator/Types.hs b/src/Graphics/UI/Qtah/Generator/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/UI/Qtah/Generator/Types.hs
@@ -0,0 +1,184 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Graphics.UI.Qtah.Generator.Types (
+  moduleNameAppend,
+  AModule (..),
+  aModuleHoppy,
+  QtModule,
+  makeQtModule,
+  makeQtModuleWithMinVersion,
+  qtModulePath,
+  qtModuleQtExports,
+  qtModuleHoppy,
+  QtExport (..),
+  makeQtEnum,
+  makeQtEnumBitspace,
+  Signal, makeSignal, makeSignal',
+  signalCName, signalHaskellName, signalClass, signalListenerClass,
+  ) where
+
+import Data.Char (toLower)
+import Data.Maybe (mapMaybe)
+import Foreign.Hoppy.Generator.Spec (
+  Bitspace,
+  Class,
+  CppEnum,
+  Export (ExportClass, ExportFn),
+  Function,
+  Identifier,
+  Include,
+  Module,
+  addReqIncludes,
+  bitspaceAddCppType,
+  bitspaceAddEnum,
+  identifierParts,
+  identT,
+  idPartBase,
+  includeStd,
+  makeBitspace,
+  makeEnum,
+  makeModule,
+  moduleAddExports,
+  moduleAddHaskellName,
+  moduleModify',
+  toExtName,
+  )
+import Foreign.Hoppy.Generator.Types (enumT, intT)
+import Graphics.UI.Qtah.Generator.Flags (Version, qtVersion)
+
+moduleNameAppend :: String -> String -> String
+moduleNameAppend "" y = y
+moduleNameAppend x "" = x
+moduleNameAppend x y = concat [x, ".", y]
+
+-- | A union of Hoppy and Qt modules.
+data AModule = AHoppyModule Module | AQtModule QtModule
+
+-- | Extracts the Hoppy 'Module' for an 'AModule'.
+aModuleHoppy :: AModule -> Module
+aModuleHoppy (AHoppyModule m) = m
+aModuleHoppy (AQtModule qm) = qtModuleHoppy qm
+
+-- | A @QtModule@ (distinct from a Hoppy 'Module'), is a description of a
+-- Haskell module in the @Graphics.UI.Qtah.Q@ namespace that:
+--
+--     1. reexports 'Export's from a Hoppy module, dropping @ClassName_@
+--        prefixes from the reexported names.
+--     2. generates Signal definitions for Qt signals.
+data QtModule = QtModule
+  { qtModulePath :: [String]
+  , qtModuleQtExports :: [QtExport]
+    -- ^ A list of exports whose generated Hoppy bindings will be re-exported in
+    -- this module.
+  , qtModuleHoppy :: Module
+  }
+
+makeQtModule :: [String] -> [QtExport] -> QtModule
+makeQtModule [] _ = error "makeQtModule: Module path must be nonempty."
+makeQtModule modulePath@(_:moduleNameParts) qtExports =
+  let lowerName = map toLower $ concat moduleNameParts
+  in QtModule
+     { qtModulePath = modulePath
+     , qtModuleQtExports = qtExports
+     , qtModuleHoppy =
+       moduleModify' (makeModule lowerName
+                     (concat ["b_", lowerName, ".hpp"])
+                     (concat ["b_", lowerName, ".cpp"])) $ do
+         moduleAddHaskellName modulePath
+         moduleAddExports $ mapMaybe qtExportToExport qtExports
+     }
+
+-- | Creates a 'QtModule' (a la 'makeQtModule') that has a minimum version
+-- applied to all of its contents.  If Qtah is being built against a version of
+-- Qt below this minimum version, then the module will still be generated, but
+-- it will be empty; the exports list will be replaced with an empty list.
+makeQtModuleWithMinVersion :: [String] -> Version -> [QtExport] -> QtModule
+makeQtModuleWithMinVersion modulePath minVersion qtExports =
+  makeQtModule modulePath $
+  if qtVersion >= minVersion then qtExports else []
+
+qtExportToExport :: QtExport -> Maybe Export
+qtExportToExport qtExport = case qtExport of
+  QtExport export -> Just export
+  QtExportFnRenamed fn _ -> Just $ ExportFn fn
+  QtExportSignal {} -> Nothing
+  QtExportEvent cls -> Just $ ExportClass cls
+  QtExportSpecials -> Nothing
+
+data QtExport =
+  QtExport Export
+  | QtExportFnRenamed Function String
+  | QtExportSignal Signal
+  | QtExportEvent Class
+  | QtExportSpecials
+    -- ^ This is a special value that is exported exactly once, and generates
+    -- some bindings that need special logic.
+
+-- | Creates a 'CppEnum' whose 'ExtName' is the concatenation of all part of its
+-- 'Identifier'.  This should be used for all Qt enums.
+makeQtEnum :: Identifier -> [Include] -> [(Int, [String])] -> CppEnum
+makeQtEnum identifier includes valueNames =
+  addReqIncludes includes $
+  makeEnum identifier
+           (Just $ toExtName $ concat $ map idPartBase $ identifierParts identifier)
+           valueNames
+
+-- | Creates an (enum, bitspace) pair with the same values and similar names,
+-- and whose enum values can be converted to bitspace values.
+makeQtEnumBitspace :: Identifier -> String -> [Include] -> [(Int, [String])] -> (CppEnum, Bitspace)
+makeQtEnumBitspace identifier bitspaceName includes valueNames =
+  let enum = makeQtEnum identifier includes valueNames
+      bitspaceExtName = toExtName $ concat $
+                        replaceLast bitspaceName $
+                        map idPartBase (identifierParts identifier)
+  in (enum,
+      addReqIncludes (includeStd "QFlag" : includeStd "QFlags" : includes) $
+      bitspaceAddCppType (identT "QFlags" [enumT enum])
+                         (Just "QFlag")
+                         (Just "int") $
+      bitspaceAddEnum enum $
+      makeBitspace bitspaceExtName intT valueNames)
+  where replaceLast _ [] = []
+        replaceLast y [_] = [y]
+        replaceLast y (x:xs) = x:replaceLast y xs
+
+-- | Specification for a signal in the Qt signals and slots framework.
+data Signal = Signal
+  { signalClass :: Class
+    -- ^ The class to which the signal belongs.
+  , signalCName :: String
+    -- ^ The C name of the signal, without parameters, e.g. @"clicked"@.
+  , signalHaskellName :: String
+    -- ^ The base name of the Haskell binding for the signal.  Normally the same
+    -- as the C name.
+  , signalListenerClass :: Class
+    -- ^ An appropriately typed listener class.
+  }
+
+makeSignal :: Class  -- ^ 'signalClass'
+           -> String  -- ^ 'signalCName'
+           -> Class  -- ^ 'signalListenerClass'
+           -> Signal
+makeSignal cls cName = Signal cls cName cName
+
+makeSignal' :: Class  -- ^ 'signalClass'
+            -> String  -- ^ 'signalCName'
+            -> String  -- ^ 'signalHaskellName'
+            -> Class  -- ^ 'signalListenerClass'
+            -> Signal
+makeSignal' = Signal
diff --git a/src/Main.hs b/src/Main.hs
new file mode 100644
--- /dev/null
+++ b/src/Main.hs
@@ -0,0 +1,108 @@
+-- This file is part of Qtah.
+--
+-- Copyright 2015-2016 Bryan Gardiner <bog@khumba.net>
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Main where
+
+import Data.Foldable (forM_)
+import Data.List (intercalate)
+import Foreign.Hoppy.Generator.Main (Action (GenHaskell), run)
+import Foreign.Hoppy.Generator.Spec (
+  Interface,
+  Module,
+  interface,
+  interfaceAddHaskellModuleBase,
+  moduleModify',
+  moduleSetCppPath,
+  moduleSetHppPath,
+  )
+import qualified Foreign.Hoppy.Generator.Std as Std
+import Graphics.UI.Qtah.Generator.Flags (qtVersion)
+import Graphics.UI.Qtah.Generator.Common (maybeFail)
+import Graphics.UI.Qtah.Generator.Module
+import Graphics.UI.Qtah.Generator.Types
+import qualified Graphics.UI.Qtah.Generator.Interface.Callback as Callback
+import qualified Graphics.UI.Qtah.Generator.Interface.Core as Core
+import qualified Graphics.UI.Qtah.Generator.Interface.EventListener as EventListener
+import qualified Graphics.UI.Qtah.Generator.Interface.Gui as Gui
+import qualified Graphics.UI.Qtah.Generator.Interface.Listener as Listener
+import qualified Graphics.UI.Qtah.Generator.Interface.Widgets as Widgets
+import System.Environment (getArgs)
+import System.Exit (exitFailure)
+import System.FilePath (
+  dropTrailingPathSeparator,
+  takeDirectory,
+  takeFileName,
+  )
+
+mod_std :: Module
+mod_std = moduleModify' Std.mod_std $ do
+  moduleSetHppPath "b_std.hpp"
+  moduleSetCppPath "b_std.cpp"
+
+modules :: [AModule]
+modules =
+  concat
+  [ [ AHoppyModule mod_std
+    , Callback.aModule
+    , EventListener.aModule
+    , Listener.aModule
+    ]
+  , Core.modules
+  , Gui.modules
+  , Widgets.modules
+  ]
+
+interfaceResult :: Either String Interface
+interfaceResult =
+  interfaceAddHaskellModuleBase ["Graphics", "UI", "Qtah", "Generated"] =<<
+  interface "qtah" (map aModuleHoppy modules)
+
+main :: IO ()
+main =
+  case interfaceResult of
+    Left errorMsg -> do
+      putStrLn $ "Error initializing interface: " ++ errorMsg
+      exitFailure
+    Right iface -> do
+      args <- getArgs
+      case args of
+        ["--qt-version"] -> putStrLn $ intercalate "." $ map show qtVersion
+        _ -> do
+          actions <- run [iface] args
+          forM_ actions $ \action -> case action of
+            GenHaskell path -> do
+              -- Generate nicely-named Qt modules that will point to the bindings,
+              -- and also contain signal definitions.
+              srcDir <- maybeFail ("Couldn't find src directory for path " ++ show path ++
+                                   " to generate Qt modules.") $
+                        findSrcDir path
+              forM_ modules $ \aModule -> case aModule of
+                AHoppyModule _ -> return ()
+                AQtModule qm -> generateModule iface srcDir "Graphics.UI.Qtah" qm
+
+            _ -> return ()
+
+findSrcDir :: FilePath -> Maybe FilePath
+findSrcDir = go . dropTrailingPathSeparator
+  where go "" = Nothing
+        go path =
+          let dir = takeDirectory path
+              file = takeFileName path
+          in if file == "src" then Just path
+             else if dir == path
+                  then Nothing  -- Can't go up any more.
+                  else go dir
