Creating custom widget is not a hard problem, but there are a few things you should consider. Here I present a simple list of what you should at least consider doing. I won’t handle the case where you build a widget that is just a container with children, because this is not a “real” custom widget. This is about creating a completely new widget that is not included in the standard list of widgets.
This blog is meant as a check-list you can go to, when you create a new widget. Just run through the items below and you are well on your way to creating a good widget that will serve you well in many different circumstances. What you won’t see here is a deep and thorough discussion of how to do each of them. But I will give you a bunch of hints and tips on how to do a properly good job when you are tasked with creating a custom widget.
The list of things you need to consider are the following:
- Create PushButton and add to window: QPushButton « Qt « C. These rights are described in the Nokia Qt LGPL Exception. version 1.1, included in the file LGPLEXCEPTION.txt in this package. GNU General Public License Usage. Alternatively, this file may be used under the terms of the GNU. General Public License version 3.0 as published.
- Mar 24, 2011 This feature is not available right now. Please try again later.
How to Expose a Qt C Class with Signals and Slots to QML. Adding custom C code is not supported when testing with QML Live. Please build your project with the classic RUN button to test the examples below. Create a C Class in your Felgo Project. After creating a new app project, first replace the code in Main.qml with this.
- Sizing for layouts
- Size policy
- Focus policy
- Painting
- QStyle support
- Input handling
- Properties
- Signals and slots
- Designer plugin
This is perhaps a surprisingly long list. And there will be some of those you won’t need to handle.
If you don’t have a lot of experience with creating custom widgets, you should go through the items below methodically. As you gain experience, this simple list will be enough. And, of course, later you won’t need it at all.
Sizing for layouts / size policy
One of the things you should always do is handle sizing. This is not needed, if you don’t use layout managers, because then the sizing of this widget will be handled from the outside. But in my almost 21 years as a Qt developer, I have so far not seen a single case where it was a good idea not to use the layouts.
The one thing you must do is to give it a size hint. Just override the sizeHint() method and return the proper size for this widget. The trick is to figure out what the proper size is. In some cases this will rely on font size, or the contents. In those cases, you need to notify the layout system that the size hint has changed, if the content or font changes. You do this by calling updateGeometry().
For a few widgets, the height depends on how wide the widget is set, or the width depends on the height. In these cases, override the heightForWidth or widthForHeight methods. Those are pretty rare, though.
It is the size policy that tells the layout managers how to use the size information from the widget. These size policies are the one thing that most other window layout systems miss, and it’s the key to fully using the Qt systems power. You need to set those correctly. In an upcoming blog entry, I will go into detail about the layouts and the size policies, so I will only briefly mention those here. In most cases you simply call setSizePolicy() with the policies for vertical and horizontal. These can be overwritten by the users of this widget class, but it’s important that you set reasonable defaults. Find the proper size policies in the documentation. It’s a good tip to look at the value, because the flags are to me a very good hint at what the size policies really do – in many cases better than the description text. Finally, remember that many widgets have different size policies for vertical and horizontal.
Focus policy
The focus policy is quite simple, as it’s only about keyboard input. There are basically only two that makes sense: No focus or strong focus.
Once you have focus, the keyboard events will go to this widget.
Note that you can get keyboard events even if this has a no focus policy, if the widget has children with focus, who doesn’t accept the keyboard events. But this is admittedly a rare thing to do. Usually, if you set no focus, then you don’t add keyboard handlers.
Painting
Unless you are creating an invisible container widget, you are of course going to need some painting. Implement the paintEvent() method. This is only mentioned for completeness, and I won’t go into details with it.
QStyle support
There are basically two things you need to do on the widget side, if you’re using a QStyle. Those are to implement the size hint and paint event by just calling the style.
In both cases, you need a style option. Initialize that and call the proper method on the current style. I usually create a private method on the d-pointer that sets up the fields of the style option. Remember that the base QStyleOption has an initFrom() method that sets up the standard QWidget fields.
Sometimes you create a custom widget that looks to the user like it’s a standard Qt widget – a QComboBox like widget, for example. The reason for doing this is to modify the default behaviour in a way you can’t do with the available API on the widget. In this case, you can reuse the styling code to handle size and painting by calling the style with the proper option object. And then you implement the input handlers to change the widget behaviour.
However, in most cases, the custom widgets require custom style code. The way to do this is usually to inherit QProxyStyle and add the code to handle your widget(s) here and call the standard code for all other widgets.
It’s not a clear cut decision whether or not to support styles in custom widgets. In some cases, the sizes and painting are going to be the same no matter what the system style is, and in that case it makes no sense at all to move the size and paint code to the style. But if you do have to implement different styles for your widget, then you should go with the style code.
It’s also a decision that can quite easily be changed later, as the code is fairly similar, whether or not it’s placed in the class itself or in a style class.
Input handling
There are a lot of input types in Qt:
- Keyboard
- Mouse
- Mouse wheel
- Touch screens
- Pen tablets (Wacom boards for example)
- Custom hardware for non standard input
All of those can have an effect on your widget, if you want them to. The most common thing is to implement just the keyboard and mouse, because for most widgets the standard conversion from touch or pen tablet to mouse is fine. But if you need the additional information from the pen strength/size etc or have to handle multi touch, then you need to implement support for these as well.
A lot of custom hardware is usually mapped to actually work with keyboard events, which saves you from handling those in some weird fashion. If this is the case, you can see the key codes that you receive from the hardware and react to those.
Handling keyboard is important even for widgets that doesn’t allow text input. For example, a button will normally allow space or enter to work as a mouse press, and radio buttons will allow keys up or down to switch the current setting. The key (no pun intended) is to try and help the user by allowing him or her to do what feels natural.
You also need to remember that input handling adds states that the painting (or the size) needs to handle. For example, a normal button has these flags that can be true or not: Pressed, focus, enabled and mouse hover. Combining those leads to a bunch of independent states that all need to be drawn differently. (None of those will affect the size of a button, but setting the text on it will.)
When you get a specification from a graphics artist on how the widget should look, one of the first things you need to do is to sit down and go through the widget states and make sure they are all covered by the spec. Because they never are. So you need a round trip to the graphics people to get a complete spec, and you might as well do the rest of the code while you wait for the updated spec.
Properties
The Qt properties serve a number of purposes:
- Tell the widget users what the properties that modify widget contents are.
- Export the property to QML code. Sure, you can’t just show a QWidget in QML, but they are also QObjects where you can manipulate the properties. It’s not a good reason in this particular blog entry, but normally it is.
- If you implement a designer plugin, the properties are available for manipulation in designer for this widget.
- Works with Qt introspection so you can list the properties and manipulate them dynamically (which is what designer does).
Of those, the first is always valid. And for this reason I tend to use Q_PROPERTY for all properties on my object classes. You should at least make the value(s) of the widget a property, but there might be others as well – headers, suffix, etc.
The only thing special (when speaking about code) to widgets about properties is if you add a designer plugin. In all other aspects, the properties have the same advantages as for any QObject subclass.
Signals and slots
Proper use of signals and slots is one of my biggest pet peeves in Qt development. If you watched my QObject Deep Dive at the Qt World Summit 2017, you will know this is an area I care a lot about.
To me, signals and slots are one of the ways you can help yourself avoid the dreaded spaghetti code. This is done by creating black boxes that do not know anything about the outside world. The Qt signal/slot system is just an implementation of the visitor pattern, where some of the work is automatically done for you.
For example, the button knows whether or not it’s been clicked. It will tell you when it’s clicked by emitting a signal. And it has no clue about what the consequence of a click is. Most developers instantly see that it’s wrong for the button to handle a click directly, by calling some function when it happens. But the same developers do not follow this for other widgets, so suddenly the changes in widget state results in a direct call somewhere.
The proper way to think about signals and slots is that it’s the API for setting and listening to an object. And two objects are connected from signal to slot by a third object that owns both of them. That owner object is the one that knows what the consequence of, for example, the click is.
When you consider which slots to offer, it’s mostly simple setter methods, when we’re talking widgets. Another usual type is to perform the action of the widget – click the button or trigger the action. For controller objects it’s not this simple, because there are a lot of slots that are connected to the action signals from the widgets. But for widgets it’s often the case that our slots are setters or actions. Most properties will have a slot, unless they are read only. There are also some methods you allow to be slots, simply because you connect them to other objects, but again this isn’t common for widgets. Except in the case where a widget has children, and in that case you usually use private slots or lambda slots to connect to the children signals.
For signals, you should communicate changes in states for your widget. It’s not all states that should be emitted as signals, for example a press by a mouse isn’t communicated, the release isn’t, but the aggregated event “clicked” is. You should also add a myPropertyChanged signal for each property.
For a longer discussion of this topic, you can watch the video with my talk from Qt WS 2017.
Designer plugin
The purpose of a designer plugin is to allow the UI/UX people and the developers to manipulate your custom widgets in Qt designer. Or in the embedded designer in Qt Creator.
When you install the plugin, you get your widget in the list of available widgets, and all the custom properties are available to set up. Also, the widget will be properly painted by the actual paint event in your widget. And you can also make it look like the proper QStyle, if you have a custom style as well.
The alternative to doing this is to use the designer promotion, where you just tell designer that you have a widget and it’s a subclass of QWidget (or QFrame, or whatever you actually have). In this case you only see the base class properties. You can in theory set the properties with dynamic properties, but please don’t. In this case, set up your custom widget in code where it is created.
Creating a designer often seems like a good idea. However, it does present you with some deployment problems, especially for large teams. Because you almost force the entire set of developers to build and install the plugin before they can use the designer. It’s not necessary for compilation, though, it’s only if you do any work in designer itself that you need it. Unfortunately designer plugins are notoriously difficult to compile, and I have seen endless questions about the plugins from the teams we have worked with. The problem is that you have to build it with exactly the same compiler tool chain as designer was built with, and you have to do it in release mode. Unless your Qt is built in debug, then your plugin needs to be built in debug mode as well. So you can’t just always use the same compiler as you build the application with, if you use the system Qt or a downloaded Qt version. It’s easier, though, if all developers work with a custom built Qt. But these days it’s rare to see that.
Final thoughts
I haven’t mentioned QML items here, since it’s about widgets. But I actually apply a lot of the same rules when creating custom items. I always have a top level Item that encapsulates the item contents. On the top level item I place the public properties, signals and functions. And I handle size, painting, input events etc. Most of the things in the list are valid for QML as well, although you have to map the concept to how QML works.
I’ll leave you with one final tip: Don’t place any logic in the widget, other than the logic necessary for the widget itself (paint states, input handling…). Logic that handles anything outside of the widget states needs to go somewhere else. Emit signals and react to those outside of the widget instead.
Home > Store
Register your product to gain access to bonus material or receive a coupon.
- By Jasmin Blanchette, Mark Summerfield
- Published Jan 15, 2004 by Prentice Hall. Part of the Pearson Open Source Software Development Series series.
Premium Website
- Sorry, this book is no longer in print.
About
Features
- Comprehensive coverage of Qt programming—The first book to provide systematic, insider-level coverage of programming with the latest and most sophisticated version of the Qt toolkit: Qt3.
Prepares students for any responsibility or challenge, either as part of an application development team or as the sole developer of a new Qt application.
- Incremental, step-by-step coverage—Starts with “Hello Qt,” and incrementally moves on to more advanced topics such as custom widgets and drag-and-drop.
Helps students gradually gain confidence as they build on what theyve already learned.
- QT signals and slots mechanisms—Thoroughly explains Qts innovative “signals and slots” mechanism for inter-object communication.
Enables students to master Qt features that make GUI programming far simpler and more reliable.
- Best practice “idiomatic” programming techniques—Provides real-world insight, not just a rehash or summary of the online documentation.
Gives students unsurpassed insight into the high-efficiency techniques the worlds best Qt programmers depend on.
- Extensive enterprise-oriented coverage—Covers Qt 3 database development, networking, XML, internationalization, and other advanced topics.
Will help students succeed even in leading-edge Qt development projects.
- By insiders at Trolltech, creators of Qt—Authored by experts who actually develop and document Qt for Trolltech.
Gives students confidence that they are receiving information that is thorough, accurate, clear, and useful—and reflects the challenges they will actually face.
Description
- Copyright 2004
- Edition: 1st
- Premium Website
- ISBN-10: 0-13-124072-2
- ISBN-13: 978-0-13-124072-8
'...not only the best book on Qt I have ever seen, but also the best book presenting any programming framework. Every sentence appears to be carefully worded, and every chapter has a sound concept, and so does the work as a whole.' --Matthias Ettrich, Trolltech's lead developer, founder of the KDE project
'The 'Tao of Qt'.... The Qt system is a beautiful example of object oriented design, and the authors take advantage of this.... The authors have done an excellent job of presenting the subject in an interesting and engaging way....' --Ron McCarty, Instructor and Chair of the Department of Computer Science, Penn State Erie, The Behrend College
The first official Trolltech guide to Qt 3.2 programming!
Straight from Trolltech, this book covers all you need to build industrial-strength applications with Qt 3.2.x and C++--applications that run natively on Windows, Linux/Unix, Mac OS X, and embedded Linux with no source code changes! The book teaches solid Qt programming practices; it is not a rehash of the documentation.
- Build powerful C++ GUI applications quickly and easily
- Design dialogs and main windows visually and in code
- Learn Qt's innovative typesafe signals and slots mechanism
- Use layouts to create forms that automatically size and scale
- Create custom signals, slots, events, and controls
- Program the 'Qt way' with techniques for Qt 3.2 that'll work with Qt 4
- Code applications with menus, toolbars, dialogs, and drag and drop
- Utilize 2D and 3D graphics, multithreading, and networking
- Write database and XML applications
- Internationalize to reach foreign markets
- Exploit platform-specific-features like ActiveX
Already using Qt or just starting out? Evaluating Qt or managing it? Building open source applications--or commercial applications? Want to develop for Windows without buying an expensive compiler? Whatever your goal, this is the only book you need!
Downloads
Downloads
Download C++ GUI Programming with Qt 3 in PDF.
Download the source document.
Extras
Related Article
Sample Content
Online Sample Chapter
Downloadable Sample Chapter
Download the Sample Chapter related to this title.
Table of Contents
Foreword.
Preface.
Acknowledgments.
A Brief History of Qt.
I. BASIC QT.
1. Getting Started.Hello Qt.
Making Connections.
Using the Reference Documentation.
2. Creating Dialogs.Subclassing QDialog.
Signals and Slots in Depth.
Rapid Dialog Design.
Shape-Changing Dialogs.
Dynamic Dialogs.
Built-inWidget and Dialog Classes.
3. Creating Main Windows.Subclassing QMainWindow.
Creating Menus and Toolbars.
Implementing the File Menu.
Setting Up the Status Bar.
Using Dialogs.
Settings.
Multiple Documents.
Splash Screens.
4. Implementing Application Functionality.The CentralWidget.
Subclassing QTable.
Loading and Saving.
Implementing the Edit Menu.
Implementing the Other Menus.
Subclassing QTableItem.
5. Creating Custom Widgets.Customizing Qt Widgets.
Subclassing QWidget.
Integrating CustomWidgets with Qt Designer.
Double Buffering.
II. INTERMEDIATE QT.
6. Layout Management.Create Custom Slots Qt C Tutorial
Basic Layouts.
Splitters.
Widget Stacks.
Scroll Views.
Dock Windows.
Multiple Document Interface.
7. Event Processing.Reimplementing Event Handlers.
Installing Event Filters.
Staying Responsive During Intensive Processing.
8. 2D and 3D Graphics.Painting with QPainter.
Graphics with QCanvas.
Printing.
Graphics with OpenGL.
9. Drag and Drop.Enabling Drag and Drop.
Supporting Custom Drag Types.
Advanced Clipboard Handling.
10. Input/Output.Reading and Writing Binary Data.
Reading and Writing Text.
Handling Files and Directories.
Inter-Process Communication.
11. Container Classes.Vectors.
Lists.
Maps.
Pointer-Based Containers.
QString and QVariant.
12. Databases.Connecting and Querying.
Presenting Data in Tabular Form.
Creating Help.
Using QTextBrowser as a Simple Help Engine.
Using Qt Assistant for Powerful Online Help.
17. Multithreading.Working with Threads.
Communicating with the GUI Thread.
Using Qt's Classes in Non-GUI Threads.
18. Platform-Specific Features.Interfacing with Native APIs.
Using ActiveX.
Session Management.
Appendices.A: Installing Qt.
A Note on Licensing.
Installing Qt/Windows.
Installing Qt/Mac.
Installing Qt/X11.
B: Qt's Class Hierarchy.Index.
More Information
Other Things You Might Like
- Book $27.99
- Book $39.99