[Qt-interest] Not use label portion of QCheckbox to activate the checkbox
Bo Thorsen
bo at fioniasoftware.dk
Thu Feb 16 09:38:38 CET 2012
Den 15-02-2012 16:18, Michael Jackson skrev:
> Is there a property that can be set for QCheckboxes to ensure that a user MUST specifically click on the checkbox part and NOT the title of a QCheckbox.
> The issue I ran into is the use of a QGroupBox with a Checkable Title. When the user is simply selecting the QGroupBox but unknowingly clicks on a part of the title, in my case, the QGroupBox is deleted. I currently use a custom Style sheet for the group box which may or may not add more complexity to the issue.
> Or should I subclass QGroupBox, or QFrame for that matter, and re-implement where the Checkbox/button are separate from the title.
No, unfortunately there isn't such a property. However, with Qt there
are options to do tricks like this when you want to.
There are a couple of ways to do stuff like this. I'll write both of
them, so you can figure out which one you'll use.
This kind of hack is something a Qt consultant like me do quite often,
and I thought it might be interesting for other people to see what you
can do.
First thing I do when I get a request like this is to ask the customer
to reconsider. I always get really annoyed when checkboxes only works
like you want them to because it's much easier to work with a checkbox
that isn't restricted to such a small cross. But if the customer (or in
this case you) still want it, then it's going to happen.
The first solution is based on controlling what area of the widget you
accept a mouse action in. Changing this is basically what you asked, so
I'll try that route first.
First part is to install an event filter and test the mouse press
position. If it's outside the box area, the press shouldn't be
registered. Don't filter out the press release, since this would be a
problem for handling the case where the user press the box and drag the
mouse outside the widget. Instead, I would modify a release event that's
outside the box to be outside the widget.
Second part is to figure out where the box is placed. This is handled by
the style (unless you have a customer painted checkbox, but I guess
not). You can call style() on the checkbox to get the style object. On
this, you need to call subElementRect with a proper set of arguments.
This means creating a QStyleOptionComplex and filling in the values. The
only way to do this right is to read the QCheckBox code and do the same.
It's very annoying initStyleOption() isn't public on all widgets for
doing stuff like this, but that's just the way it is. The rect given
here can determine whether the click is in the box or not.
There is another way, and it's probably the one I would use in this
instance. The trick here is to use a proxy style. This is a generic
trick that can be used for *a lot* of weird hacks. However, be warned
that on Mac there are some problems with proxy styles because the Mac
style is broken (IMHO). It checks if the style on the widget is the
native style and if so does some things different. So when you install a
proxy style object, weird things happen to a couple of widgets. I don't
think QCheckBox is one of them, though.
A proxy style is a QStyle subclass where all methods just call the same
method on another style object. Except for the things you want to
change, of course. This class would look something like this:
class CheckBoxProxyStyle : public QStyle {
public:
// Most methods just call the other style object
void polish(QWidget* widget) { qApp->style()->polish(widget); }
...
QRect subElementRect(SubElement element, const QStyleOption* opt,
const QWidget* w) const
{
if (element == QStyle::SE_CheckBoxClickRect) {
return subElementRect(QStyle::SE_CheckBoxIndicator, opt, w);
return qApp->style()->subElementRect(element, opt, w);
}
};
This is completely untested, so there might be some odd case you have to
worry about. But the idea should be clear enough, I hope.
Don't attempt a fix that doesn't include calling the QStyle options
because this will break when the user runs the application with another
style. Even if you disallow this, you are still going to have the
problem when you port the system to another version of your OS.
Bo Thorsen,
Fionia Software.
--
Expert Qt and C++ developer for hire
Contact me if you need expert Qt help
http://www.fioniasoftware.dk
More information about the Qt-interest-old
mailing list