Programmatically Cycle through Tab-Order in QT5 - qt

I have a QT5 application in which I have to simulate a tab keypress on an external event i.e. I need to cycle through the taborder list and setFocus on the next element.
I cannot find any method to get the tab-order list programmatically. What would be the best way to do this?

How about a combination of QWidget:: nextInFocusChain() / previousInFocusChain() and setFocus() method or setFocus() slot? (There are some other ways to set focus as well, all cross-linked in the Qt docs.)
nextInFocusChain()and previousInFocusChain() provide public API access to the underlying private members which seem to control the tabbing order. You can see them being used in QWidget::setTabOrder() for example.
Current focus widget could be found with either QWidget::focusWidget() of the parent widget, or QApplication::focusWidget(). Note that QWidget::focusWidget() will also return the first widget in the focus order if none currently have focus. This starting point could be used to build a list of widgets in tab order.

Related

Qt event for delegate in table

Question/Issue
I tried reimplementing the event method in a custom delegate to handle clicks. The delegate is used to render table cells in a table view. However, I do not get any events for the delegate (the method is never called according to the debuger). Is there anything special I need to do so my delegate can track events (in particular mouse entering/exiting, clicks)?
Context
I would like to create my own data representation for table cells. The functionality should be close to a button, but slightly different. I read that the two options for implementing buttons in table are either setting a cell widget which supposedly has a high performance cost (I did not quite understand why) or using a delegate.
Since I want different behaviour than that of a button, and for the speed myth I decided to go with a delegate.
Mouse events are send to the QAbstractItemDelegate::editorEvent() method, even if they don't start editing of the item.
See: http://doc.qt.io/qt-5/qabstractitemdelegate.html#editorEvent

Add a delete Button to each Item in QListView

Is it somehow possible to add to each Item in a QListview a Button which is deleting the Object onClick? As shown in the following Picture:
EDIT: As I'm new in QT it would be nice to have some example, to understand it better. And as it seems there are three different Ways? What will be the best? Do use a QAbstractItemView?
Yes. You'll need to use:
QAbstractItemView::setIndexWidget ( const QModelIndex & index, QWidget * widget )
QListView inherits QAbstractItemView and when you're trying to customize list/tree views that's usually the place to look. Be careful though, without a delegate this doesn't scale very well. Check out this thread: http://www.qtcentre.org/threads/26916-inserting-custom-Widget-to-listview
You can also go for a generic approach that can work on variety of containers, including the underlying model of your list view.
Each item in the list has a requestRemoval(Item*) signal and a removeMe() slot, connect the X button to the removeMe() slot in each item constructor, in removeMe() you emit the requestRemoval(this) signal, which is connected to a removeHandler(Item*) slot in your "parent" object upon creation of that item, which receives the pointer of the item which has requests deletion, and removes it from the underlying container being used.
Basically, pressing the remove button causes that particular item to send a pointer of itself to the parent's remove handler which removes that entry.
EDIT: Note that this is a generic approach, as noted in the comments below it can be applied without signals and slots as well, and even though it will work it is not the most efficient solution in your particular case.

Post events without specifying target object in Qt

I need help to understand to use QEvents in QT, this is driving me crazy.
I am writting an application using custom events, but as in QApplication::postEvent function, it's necesary to specify the target object.
As I understand, it's possible to post events to Qt's event loop with
QApplication::postEvent(obj_target, QEvent myevent);
This means that I'm trying to catch "myevent" event in obj_target an do some stuff.
But I need to post events without specify a target object, as QMouseEvent or QKeyEvent do
I mean, when clicking in a QMainWindow with a lot of buttons, how is that I can click
any button and that button is pressed?
What is the target object when the click event is posted?
It's possible to register objects to "listen" for a specific event?
I'm really confused, it's possible to post an event without specifying a target object?
Thank you very much in advance
There is no trivial way to post events "globally", as Dan has said. All of the event dispatching of native events is done by private Qt implementation code.
The important distinction is:
There are native messages/events, delivered by the operating system, usually received by a window-specific event loop.
There are QEvents.
Internally, Qt keeps track of the top-level Widgets (windows, really), so when it receives an event from the OS, it knows which window it should go to - it can match it using the platform window id, for example.
QEvent delivery makes no sense without a receiving object, since sending an event to an object really only means that QObject::event(QEvent*) method is called on that object. It's impossible to call this method without having an object instance!
If you want to synthesize a global key press or mouse click event, then you have to figure out what object the event goes to. Namely:
Identify what top-level window (widget) the event should go to. You can enumerate top level widgets via qApp->topLevelWidgets().
Identify the child widget the event should go to. If it's a keyboard event, then sending the event to currently focused widget via qApp->focusWidget() is sufficient. You need to enumerate the child widgets to find the deepest one in the tree that overlaps the mouse coordinates.
Send the correct QEvent subclass to the widget you've just identified. Events delivered to top-level widgets will be routed to the correct child widget.
When sending mouse events, you also need to synthesize relevant enter and leave events, or you risk leaving the widgets in an invalid state. The application.cpp source file should give you some ideas there.
This doesn't give you access to native graphical items, such as menus on OS X.
Please tell us exactly what you're trying to do. Why do you want to post a broadcast event? Who receives it? Since your own QObject-derived classes will receive those broadcasts, I presume, it's easy enough to use signal-slot mechanism. You'd simply connect(...) those receiver classes to some global broadcaster QObject's signal(s).
For this purpose, I have a specific singleton class which I call GuiSignalHub. It regroups all the application-wide signals.
Objects that want to trigger an application-level action (such as opening context help) just connect their signal to the GuiSignalHub signal. Receivers just connect the GuiSignalHub to their slot.

Qt: How to initialize dialog widgets?

I would like to know what the established procedure is for initializing the controls within a Qt custom dialog box. In the code I am writing, the dialog would present a QListView containing directories from an object passed (by reference) to the dialog class during construction. When the dialog is displayed, I obviously want the list to display the directories currently configured in the object.
Where should this be done though? Perhaps in the overridden showEvent() method?
Background: I used to do a lot of MFC programming back in the day, and would have done this sort of stuff in the OnCreate method, or some such, once the window object had been created.
Thankfully Qt doesn't require you to do any hooking to find the moment to create things (unless you want to). If you look over the Qt examples for dialogs, most do all the constructing in the constructor:
http://doc.qt.io/archives/qt-4.7/examples-dialogs.html
The tab dialog example--for instance--doesn't do "on-demand" initializing of tabs. Although you could wire something up via the currentChanged signal:
http://doc.qt.io/archives/qt-4.7/qtabwidget.html#currentChanged
Wizard-style dialogs have initializePage and cleanupPage methods:
http://doc.qt.io/archives/qt-4.7/qwizardpage.html#initializePage
http://doc.qt.io/archives/qt-4.7/qwizardpage.html#cleanupPage
But by and large, you can just use the constructor. I guess the main exception would be if find yourself allocating the dialog at a much earlier time from when you actually display it (via exec), and you don't want to bear the performance burden for some part of that until it's actually shown. Such cases should be rare and probably the easiest thing to do is just add your own function that you call (like finalizeCreationBeforeExec).

With several widgets sharing the same signal slot (event handler), how do I find out which one has been clicked?

In my project I am using a custom circle-shaped button widget derived from the QWidget class. I have added several of these widgets to a parent widget.
When one of these custom buttons is clicked, how do I find out which one was clicked?
Adding custom button to parent widget:
void ShotViewCTRL::addShot(QString shotNanme)
{
ShotButton *btnShot=new ShotButton(this);
btnShot->shotName=shotNanme;
connect(btnShot,SIGNAL(Shot_Selected()),this,SLOT(SHOT_CLICKED()));
btnShot->CreateButton();
btnShot->show();
}
My parent widget is ShotViewCTRL (inherits from QWidget), the child widget is ShotButton (custom control, inherits from QWidget).
The control is working fine. It's sending sending to parent object. In my problem, I added the same custom control 10 times.
I need to find which control was clicked? Please help me find the solution.
I have referred to the Qt documentation to find the child widget, but I did't understand. Some sample code would be great.
QSignalMapper is what you are looking for. With QSignalMapper, you can add something like an Id (or even a pointer to the QButton itself) as additional data to the signal emittance and you have to adjust your slot so it takes additional data (ID or Pointer).
Then either distinguish in the slot itself by the id you give your objects some virtual function type() so you can distinguish with that or even try casting and catch errors (Tip: don't try the last method, it may work differently on different compiler).
You can use the QObject::Sender function to find which QObject sends the signal. Regarding the first warning in the doc, it's what you are searching for.
you specify different slots for different buttons with same signal.with that you can recognize the different button click

Resources