How to set accessible name of QActions contained in a QMenu - qt

I'm trying to set the accessible properties of a QMenu's sub items. I can set the accessible property of the parent menu using setAccessibleName() since it inherits QWidget. Unfortunately, the QActions that you add to the menu aren't widgets child classes, they inherit QObject directly.
Is there a way to set the menu items accessible name?
Thanks

I've never used this aspect of Qt but it looks like you have to use the QAccessibleInterface framework.
There is a subclass of this for QObject, namely
QAccessibleObject. This still has some pure methods from the base so you'll need to provide some methods.
From what I can gather from a quick look at the documentation you can either provide a QAccessibleObject wrapper for the whole menu or for each action individually. If doing the latter then you would implement childCount() to return 0 and role(int i) to return QAccessible::MenuItem.

I'm not sure if this would work in your case with menu, but I solved mine where o->parent() returns QObject like this.
dynamic_cast<QWidget*>(o->parent())->setAccessibleName("whatever");

Related

I want to extend dropEvent() (QListWidget), should I completely reimplement it?

I have a QListWidget and I have set it to accept drops, the mode to be DragDrop etc and I can move QListWidgetItems all around the place (inside the QListWidget of course).
I like this behavior and I want it to let it as is, but I also want my QListWidget to accept drops from a QTreeWidget as well. If I attempt to reimplement the dropEvent() of my QListWidget then I lose the default behavior.
Is there any way to just extend the current behavior so as to have both drag-drop between listwidget items and drag-drop from the treewidget to the listwidget or I have to completely re-write both behaviors in my dropEvent() reimplementation?
Thanks a lot for any answers :)
Two ways:
implement a standalone event filter and make it act upon QEvent::Drop. Install it on your original QListWidget. Return false so that the original dropEvent() handler is called afterwards.
inherit from QListWidget, reimplement dropEvent(evt) and as a last statement, call QListWidget::dropEvent(evt);. Your original behavior will be retained.
No.
Subclass QListWidget, reimplement
virtual void QListWidget::dropEvent ( QDropEvent * event )
and explicitly call
QListWidget::dropEvent(event);
whenever you need the default behavior.
How to call a parent class function from derived class function?

QWidget stays within parent QWidget

i'm quite new to Qt and i've a question.
I've got an application with multiple windows/QFrame. I'd like them to only exist within the mainwindow (it's also the parent gadget). When I move them, I want the to stay within the parent gadget.
Is is possible ?
If yes, how ?
I've been through the Qt doc and i've found nothing. I though maybe a simple option can do that. Or do I have to create a new Widget with customs mouse Event methods ?
Thx
If you want a Multiple Document Interface (MDI) GUI you can use the QMdiArea and QMdiSubWindow classes to implement this. Have a look at the detailed description section of QMdiArea for using it with a QMainWindow example, but it also works on any other widget as well.

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

How to subclass a widget to add more elements to it?

I'm trying to make a subclass of QTableView that has an embedded QLineEdit at the top for filtering the results as-you-type. I need my table to have the same API as a normal QTableView, so I want to subclass it rather than subclassing QWidget and adding a QLineEdit and QTableView to it.
I thought I could just re-implement paintEvent(QPaintEvent*), alter the QPaintEvent's rect() to start a bit lower (the height of a QLineEdit, so it draws under it) and then pass it thru to QTableView::paintEvent(), but the QPaintEvent argument only dictates what region needs to be repainted, not the region where the widget should be painted.
Anything you do in this regard is going to be hacky and result in just as much work (probably more work) as manually mapping all of the signals and slots to a child widget. You'll need to do a lot more than just change the paint events, you'd also have to adjust all of the mouse events, adjust any update rectangles, etc.
Alternatively you could just take the QTableView class from the Qt source and modify it directly (though that will probably break the LGPL and require you to publish your source if you don't have a commercial license.) But the easiest clean method is going to be implementing a container widget with the QTableView as a child.
I would try overriding the paintEvent, changing the widget::pos to be abit lower than it is and call QTableView::paintEvent()
I have to agree with Daniel: I don't think this is the right approach. You will likely want to create a custom widget with a line edit for performing the filtering. Otherwise, you will be entering into the challenging world of Qt hacking.
If you really need to provide access to the QTableView interface then simply add a public get method that returns a reference to the table.
This is somewhat similar to how Qt provides a QTabWidget class that inherits QWidget but has a private QTabBar that it uses internally. One significant difference is that it provides a protected tabBar() accessor rather than a public one.

how can I have more than a UI for a QMainWindow?

I would like to have a QMainWindow that can change it's look at runtime, i.e when a user clicks a button. Besides keeping references to different UI classes generated by the QtDesigner, is there another way of doing that? Maybe by storing each UI in a layout ? What do you think ?
How much of the main window do you want to change? You could use a QStackWidget any place you want to change things, and change the shown page of the widget when the button is pressed. This will be quick to change, but for large or complicated UIs it may be slightly slower at startup, since it will be creating the widgets for both UIs at the same time. (There are fairly easy ways to change this, also, but they do add complications to something that could be straightforward for most people.) Also, if both layouts should have the same data, just in different places, you have the additional overhead of keeping both sets of UIs up to date while the program is running.
I think I got it now.
You have a QMainWindow and when a certain event is triggered you want to change the appearance of that particular window, like remove some buttons, add a treeview widget or what not.
Well the straight forward approach would be to do it manually, remove some widgets and add new ones using regular C++ code. This can be abit hard if you're used to Qt Designer.
The other way I can think of is using Qt Designer to generate the code for the other appearances and copy it to a special function. The code generated by Qt Designer is usually in a header file called "ui_classname.h" and isn't hard to understand. You will however need to remove some of it as not all would be necessary.
Also, instead of copying the generated code from Qt Designer you could just call it. Usually your widget has a pointer to the generated class and in your widget's constructor you see something like this:
MyWindow::MyWindow(QWidget *parent) : QMainWindow(parent), m_ui(new Ui::MyWindow)
{
m_ui->setupUi(this);
}
and in the corresponding header file:
class MyWindow : public QMainWindow {
...
private:
Ui::MyWindow *m_ui;
};
You could add the additional generated classes for the other appearances and use them when your event triggers.
It might look like this:
class MyWindow : public QMainWindow {
...
private:
void changeAppearance(int id);
Ui::MyWindow *m_ui;
Ui::MyWindowFirstAppearance *m_uiFirst;
Ui::MyWindowSecondAppearance *m_uiSecond;
...
};
void MyWindow::changeAppearance(int id)
{
// some code to remove the current appearance, basically the opposite of what setupUi is doing
if (id == 0)
m_ui->setupUi(this);
else...
m_uiFirst->setupUi(this);
...
}
This has the benefit of using the generated classes directly, so every change you do in Qt Designer doesn't require a change to your main window. The problem is I'm not sure if it's legal to call setupUi more than once and in a place other than your widget's constructor, so you'll have to check that (by looking at what's happening in the setupUi function).
You can dynamically load UI layouts at runtime. Check Qt documentation for QUiLoader class.
This also enables you to upgrade UI layouts without modifying a single line of code.
What I do is to design two UIs under two different QFrames, put the two QFrames in a layout together in the QMainWindow, and then hide() and show() the correct QFrame that you want...
You can use a QTabWidget and hide its buttons. You can then design each GUI in a separate window of the tabWidget. It has the advantage over hiding frames that you won't clutter up your Qt Creator window.
If I'm getting this right, I think you might want to take a loot at style sheets. It allows you to have "skins" for your widgets, much like CSS.
If I didn't get this right, and what you're trying to do is generate .ui files on the fly and create widgets with those using QUiLoader, then you're probably going at this the wrong way since I can't think of a good reason a regular application would need that.

Resources