Qt Design Promoted Qpushbutton parameterised constructor - qt

I've been learning about subclassing and widget promotion in Qt Designer and I've promoted some QPushButtons. My promoted class represents the number keys on a calculator, and takes a parameter in the constructor. The parameter given is the number of the button and it is passed in as an int.
Is there a way to tell Qt Designer how to construct each button? The constructor needs the numbers 0-9 passed to it. If I manually modify the generated code it works; however, each time it generates the form, I have to manually edit it.

There is no simple way to achieve this while keeping your argument in the constructor I'm afraid (read this page in the docs to how you might go about it).
I think your best solution is to keep the constructor mirroring that of QPushButton (i.e. just passing a parent QWidget) and set your custom data by calling a function afterwards.

Related

Automating a custom QGraphicsObject control in an external QT based process

I have injected a DLL into an external application that is based on the QT framework. I then use the command QApplication::allWidgets() and iterate through the list of widgets to find a QGraphicsView that represents the window I want to interact with. The buttons and other controls in the scene are all derived from QGraphicsObject. I don't have the source, so I can only cast to QGraphicsObject and not the actual type. The list of methods from the metaobject is incomplete, which is to be expected, because I cast to a QGraphicsObject. I can find the method names using IDA though. Is it possible to call a particular method, and how would you do it?

Specifying Delegate class for a QAbstractItemModel item

I have a Qt C++ application that uses several different models (ultimately) based on QAbstractItemModel.
Several of the items in these models use a custom Delegate to render them properly, these work well.
However, I'm not sure how best to specify which of these Delegate classes should be used to render the data.
At present, I'm calling QAbstractItemView::setItemDelegateForColumn() in each of the forms that contain a view.
This feels very clumsy, because it relies on the form classes knowing which delegate should be used for each column in every model - and if that changes in the future, I have to update every form.
Furthermore, in some cases a View is switching between two different models that require different Delegates, so for these the form class has to handle that switch as well.
Is there a better way to do this?
The model must not know about representation, so you should deal with the view. You can subclass involved view class (e.g. QTableView) and reimplement setModel virtual method. In your implementation call the parent class implementation and adjust item delegates based on specified model. Put objects of this class inside all your forms. So forms will not know about delegates. I think this approach agrees with the Model-View conception.
AFAIK, there's no better way.
However, instead of updating manually every form, i used to have an enum which holds the columns index, which is used both in the model and in the view to retrieve data and apply delegates.

How can I stop Qt::ForbiddenCursor from appearing during a drag?

I'm implementing a drag and drop interface with Qt across X11 and Windows. The interface handles events such that it is not illegal for a user to drop a dragged object on an area which can't handle drops.
In this case, Qt::IgnoreAction should therefore not be treated as an incorrect potential action. To communicate this fact to the user I need a way to stop Qt::ForbiddenCursor from displaying if the current Qt::DropAction is Qt::IgnoreAction.
There are three ways I can see to achieve this (in order of preference):
To override the QCursor used for a drag with Qt::IgnoreAction to something other than Qt::ForbiddenCursor.
To override the bitmap used for Qt::ForbiddenCursor. This is pretty dirty but would be an acceptable solution as long as I don't have to delve into OS-specific configuration.
To override the call made by Qt when a drag leaves a valid drop area (I assume that Qt does the equivalent of QDropEvent::setDropAction(Qt::IgnoreAction) in this case).
Could anyone suggest ways to acheive any of the above?
Note: I have also attempted to use QApplication::setOverrideCursor() just before calling QDrag::exec(). This doesn't seem to have any effect.
Check if QDragEnterEvent comes to application itself (install event filter on QApplication object). If it does, simply accept it and cursor will appear normal.

How to efficiently handle multiple qspinboxes each changing a separate class variable

I have a class with many private variables which I need to be able to modify with qspinboxes. I can do it by having a seperate slot for each variable connected to its particular spinbox but the code is getting lengthy and repetitive.
I really want to have a single slot which takes the address of the variable to change and its new value. I think I could somehow use qsignalmapper for this but I can't figure out how. Can anyone help? -preferably with an example as I am a novice QT programmer.
I am using Qt4 with C++ and Fedora 14
What you most likely want to do is create a custom subclass of the spin box that can also keep track of 1 variable to modify. Create your custom subclass instead of the spin box, and for each spin box, pass the variable that it is supposed to be able to modify. Inside your custom class, you have one slot, which modifies the variable it knows about.
There are variations on this idea, but it is a simple way to reduce all of that repetition.
Trust me, you'll want to slog it out and just have a bunch of repeated connect() lines, and member access functions. It's not that bad. QSignalMapper is meant for parameterless signals, and to relate them with integer ID's or pointers to QObjects. That's not your scenario.

Updating a QListView when objects change externally

I've a simple question regarding the update of a QTreeView (or any subclass of QAbstractItemView) when a model object changes externally. Let's say that a list shows a subclass of QAbstractItemModel, and an item of that model gets changed outside of the list window, and we would like to update the list with the change. What is the usual strategy to achieve something like this ? I've looked at the Qt documentation of QAbstractItemModel and there is a signal named 'dataChanged' that is (or should be) emited when data from the model changes. But since this signal (as all QAbstractItemModel functions/signals/slots) work with a QModelIndex, which is not persistent as the documentation clearly says, am i supposed to store somehow a mapping of my data to QPersistentModelIndex(es), so when my data change i will be able to find the corresponding QPersistenModelIndex and use that as argument to the various QAbstractItemModel functions ? Is that what QPersistentModelIndex(es) are used for ? Or am i missing something ?
Thank you.
ps: I guess i could just reload the QTreeView, but then i wouldn't know which items were expanded or which were selected. Is there an strategy to overcome this problem and just reload the list ?
QTreeView already handles the case in which the underlying model's data changed (i.e. the model has emitted the dataChanged() signal). That means you don't need to do any additional work on the view.
If you're implementing your own model (a derived class of QAbstractItemView), and you're making a change to the contents of the model, you simply need to emit the dataChanged() signal when your change is complete. The signal/slot mechanism will automatically inform the view using that signal.

Resources