In MFC, I am trying to split a window into two panes. I need left pane should be fixed. i.e., If I drag, it should not expand. How can I implement this ?
Use a class that you derive from CSplitterWnd. In your derived class handle the mouse messages by doing nothing. I.e., do not call the base class handler, so the CSplitterWnd class will not see the mouse actions.
Related
I'm using a QGraphincsView that holds several elements which inherit from QGraphicsItem. The whole thing works fine, I can select them as desired. And when I hold down the Ctrl-key I can select several of them.
Now I want to implement an optional multi-selection without the need to hold down Ctrl-key. I already tried to set the related modifier in mouse-press-event by calling
evt->setModifiers(Qt::ControlModifier);
before the event is handed over to it's base-class QGraphicsItem but this does not work.
So my question: what has to be done to get multiple selection functionality by default and without holding down a key?
Thanks!
This is controlled by the QGraphicsScene. You stated: -
I'm using a QGraphincsView that holds several elements which inherit from QGraphicsItem
This is not actually the case. A QGraphicsView is a window into an area of the scene; it is a QGraphicsScene which holds items derived from QGraphicsItem.
You can see in the documentation that the QGraphicsScene has functions such as selectedItems(), selectionArea() and setSelectionArea(). While a QGraphicsItem can be selected with QGraphicsItem::setSelected, the control of what happens when you click an item is governed by the QGraphicsScene, with the event having been passed from the QGraphicsView.
If you inherit from QGraphicsScene, you can override the mouse methods; mousePressEvent, mouseMoveEvent, mouseReleaseEvent. This will allow you to monitor when the user selects consecutive items by clicking on them and react by calling their QGraphicsItem::setSelected function.
Alternatively, depending upon your design, you can allow the user to draw an area on the scene and call QGraphicsScene::setSelectionArea, which will set all the items surrounded by the given QPainterPath.
I've a MFC dialog and an ActiveX grid control on it. Whenever user tries to edit a date type grid cell, I'm creating a CDateTimeCtrl and showing inside the grid. This control is being created as a child to the grid control, but is a variable in the dialog class.
Now, I'd like to handle the DTN_DATETIMECHANGE message of this date control in my dialog's class. I can see in Spy++, that these messages being sent to the grid control, but how do we handle this in the grand parent's (dialog) class?
Have you tried creating it as a sibling, but just higher in the Z order? You might need to add WS_CLIPSIBLINGS to the parent dialog's style to avoid issues where the grid paints over the date control.
An alternate techique is to use an intermediate child that acts as forwarder, so grid contains forwarder which contains date control. That way your code still receives the notifications; and you still get the appropriate HWND containment effects. (The forwarder typically has no border, and just resizes its only child to take up its entire client area, so is not visible to an end-user.)
I have the following problem with Qt (no answer on this site seemed to address exactly this problem so I create my own question).
I have an application with a MainWindow class which inherits from QWidget. At a certain point there is a table inside the main window and I want to catch all mouse pressed events outside that table.
My first solution was to reimplement the method
/* virtual */ void MainWindow::mousePressEvent(QMouseEvent *event)
In this method, I check the position of the event and check that it is not within the QRect of the table. Unfortunately, I realized that mousePressEvent() is not always called. I suspect that if I click on another child widget of MainWindow, that widget consumes the event and does not pass it through to the parent.
So the only alternative idea I had was to reimplement the mousePressEvent() method for all the widgets contained in MainWindow. This is of course not feasible, because:
There a lot of them: it would be very complex, time-consuming, error-prone, and difficult to maintain if one had to change all the widget classes that are instantiated inside MainWindow.
Some of the subwidgets are implemented in some library modules developed in a parallel project, so I cannot change those.
In other cases, the subwidgets use Qt classes directly.
Even if I defined custom subclasses for 2 and 3, I would have to make sure that these subclasses are used everywhere instead of the original classes. This might imply again falling back to case 2.
So this alternative solution seems unfeasible to me.
Summarizing: Do you know if there is a simple method to catch all mouse clicks on the main window from within the MainWindow class?
You could do this by installing an event filter in the main window. Take a look at QObject::installEventFilter() in the Qt docs.
You can set the attribute Qt::WA_TransparentForMouseEvents with QWidget::setAttribute to all the child widgets except the table to get the mouse events in the MainWindow (which will only work if the table is a direct child of MainWindow).
Or do the opposite, and add a transparent widget above your whole MainWindow with a hole at the position of the table. And you set/unset the Qt::WA_TransparentForMouseEvents to that widget when you want it to let the clicks pass or to catch them.
The hole can be created with QWidget::setMask() and QRegion::substracted().
For my Gui I want to use the following system:
The way it works is that, if the widget under the mouse does not consume a mouse or kb event, it is passed to that widget's parent until it is consumed or the desktop is reached.
Just one thing puzzles me about it. Does that mean if a Button, for whatever reason has a Label as one of its children. If I click the label, would that not mean that my button, which is under the label would click (since a label does not consume the mouse), which is undesired in this case. Does that mean I'd have to do if(mouseEvent.source == this){do button stuff} ?
Thanks
If the label is a child widget, then yes, the label will attempt to eat the event, fail (as usually the label doesn't have a handler method) and thus pass the event back up to the button.
Chances are the easiest way to do this is to derive a subclass of the Label class, and override the handle function (assuming this is possible in your toolkit - which it should be in any decent toolkit). You can then use your handle function to capture mouse clicks, and pass any other event back up to the button.
Comparing pointers is probably a bad idea and is slightly dependent on the way the toolkit is implemented - for instance, it might deem the source as the button (because that's what it expects), not the label.
Though I find it highly strange that a Label is a widget in itself.....
It looks like you need a special kind of "Label" which consumes mouse events. You should be able to create a customized widget (derived from Label) that consumes mouse events for this specific case.
If that Label widget is from a third party that cannot be derived/subclassed, you should wrap the Label in another widget: A simple widget that consumes mouse events and has only one child, the original Label.
Is there something like a panel that I can use in a MFC application. This is to overlay the default window in MFC (a dialog application). Then to paint the panel black and paint some random stuff on top of it. Something like a view port.
is there a better option than this to achieve the same effect ?
Sure. It's called a window! Create a class that derives from CWnd and overrides OnPaint().
In your dialog's OnInitInstance(), instantiate a CMyWnd object and call it's Create() member. Of course, make sure the lifetime of your CMyWnd object is the same as the dialog's object lifetime window. iow, make it a member of you CMyDialog class.
Not very complicated but obviously an area where MFC shows why it doesn't fall in the RAD tools category.
Another solution would be to derive from CDialog. This way you can use the resource editor to edit the panel visually and you don't need to paint anything yourselve. Also the Panel class is rather thin and just needs to propagate the Create() and Show() calls to support subpanels and multiple panels within a single form.