Unable to display Widget when passing this as the parent when initiating - c++

Hi Im learning QT and I have come across something I don't understand. why is it when I create a widget like so
widget = new Widget(this);
widget->show();doesn't display the widget, but if I leave the 'this' out i.e
widget = new widget();
It does display? whats more I need to be able to call one of the parent's methods from the child and unless I set the patient of the child by passing this upon its creation I am unable to do this.

The widget does show up. But it shows up as part of the main window, not in its own window. Of course if the widget you're creating doesn't have any content in it, then you won't see much. You can test this with something like:
widget = new QTextEdit(this);
widget->show();
If you want to make the widget always show up in its own window, then you should have your widget inherit from QDialog instead of from QWidget. Or, if you don't want (or can't) do this, then you should set the Qt::Window window flag when creating the widget:
widget = new Widget(this, Qt::Window);

Related

How do I set the parent of a widget after the widget has already been initlized (ex. if the widget is a parameter to a function call)?

I know that usually parents are set by being given in the constructor argument, for example if you wanted to have a push button within a frame you could do:
QFrame frame = new QFrame();
QPushButton* button = new QPushButton(frame);
But I already have the push button that I want to add as a child to a frame (it was received as an argument in the call to the function I'm working on).
Is there any way to add an already existing widget as a child to another widget? Or add a new child to an existing or nonexistent parent?
(Disclaimer: Answer blatantly stolen from G.M.'s comment (with permission - see above ;))
Simply use QWidget's setParent(QWidget *parent) method.
Note: The new parent takes ownership of the QWidget (i.e. deallocating it when the parent is destroyed etc.) and you will need to call show() on the widget again to make it visible, as changing parents turns QWidgets invisible.

Qt5 QMainWindow components deletion

One of our teacher asked us to create a Qt application without any UI file for the main window (a QMainWindow). Usually I always create one, leave it empty and let the uic deal with it.
I know that if a parental relation is defined between a widget (child) and its parent, then there is no need to delete the widget (deleted when the parent is deleted). So, when the UI is deleted, all the children are destroyed.
If we do not use an UI file (not generated), do we have to manually delete all the widget added to the GUI?
A little sample:
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent){
layout = new QHBoxLayout(this);
aButton = new QButton(this);
layout->addWidget(aButton);
...
}
MainWindow::~MainWindow(){
delete ui; // No need to delete more if parental relation.
// However, what do we do if no ui has been generated?
// Do we have to delete aButton?
}
The value of parent is 0. It is the main entry of the application.
Thanks
Please refer to this article
QWidget, the fundamental class of the Qt Widgets module, extends the parent-child relationship. A child normally also becomes a child widget, i.e. it is displayed in its parent's coordinate system and is graphically clipped by its parent's boundaries. For example, when the application deletes a message box after it has been closed, the message box's buttons and label are also deleted, just as we'd want, because the buttons and label are children of the message box.
So, there is no difference do you use ui or not. When you delete window, all its children will be deleted too.

How to install eventFilter on dynamically created QWidget?

i have just one QMainWindow with mainwindow.ui where i have tables, buttons etc...
From one button i want to dynamically create widget and set an evenFilter on it.
QWidget dialog = new QWidget();
dialog->installEventFilter(this);
When i compile program it says that QObject::installEventFilter(): Cannot filter events for objects in a different thread.
How can i add this widget to thread with other Qobjects or what is best solution to this problem?
You should not create gui widgets from non gui threads.
Create subclass of QWidget and install there eventFilter, put inside signals to return result back.
And than send signal from your thread to main thread slot to create this QWidget dialog = new MyWidget() and use as you want.

How to add QLabel to QGraphicsItem

I have a QGraphicsItem that has text on it. I want this text to be editable, so that if the user double-clicks it, it will enter an edit mode. It seems like the easiest way to do this would be to change the text into a QLineEdit and let the user click away the focus or press enter when they're done.
How can I add a QLineEdit to a QGraphicsItem? I have subclassed the QGraphicsItem so I have access to its internals.
To add any QWidget based object to a QGraphicsScene, a QGraphicsProxyWidget is required.
When you call the function addWidget on QGraphicsScene, it embeds the widget in a QGraphicsProxyWidget and returns that QGraphicsProxyWidget back to the caller.
The QGraphicsProxyWidget forwards events to its widget and handles conversion between the different coordinate systems.
Now that you're looking at using a QLineEdit in the QGraphicsScene, you need to decide if you want to add it directly:
QGraphicsScene* pScene = new QGraphicsScene;
QLineEdit* pLineEdit = new QLineEdit("Some Text");
// add the widget - internally, the QGraphicsProxyWidget is created and returned
QGraphicsProxyWidget* pProxyWidget = pScene->AddWidget(pLineEdit);
Or just add it to your current QGraphicsItem.
Here, you can either add it as a child of the QGraphicsItem:
MyQGraphicsItem* pMyItem = new MyQGraphicsItem;
QGraphicsProxyWidget* pMyProxy = new QGraphicsProxyWidget(pMyItem); // the proxy's parent is pMyItem
pMyProxy->setWidget(pLineEdit); // adding the QWidget based object to the proxy
Or you could add the QGraphicsProxyWidget as a member of your class and call its relevant functions, but adding it as a child is probably much simpler.
QGraphicsTextItem::setTextInteractionFlags (Qt::TextInteractionFlags flags)
API can be used. But you need to create QGraphicsTextItem inside it.
Please check following link for details: Implementation details
You need to create a proxy widget by extending QGraphicsProxyWidget in the case you need some specific behavior or just use a QGraphicsProxyWidget. Take a look at the "Embedded Dialogs" example in your Qt SDK and the QGraphicsProxyWidget documentation. It has been there for a long time so it should be for your version. I hope this helps.

Use custom tab bar with QMdiArea

I see that QMdiArea has a tabbed view mode. I want to be able to split the main window with two QMdiArea widgets and to be able to drag and drop tabs between each of them. I have already done it with a simple QTabWidget where I can set custom tab bar. At the same time I want to switch QMdiArea view mode thus using QTabWidget is not an option for me. But I don't see any methods to set custom tab bar within QMdiArea. I still have hope that it could be done. Can anyone suggest something?
Tested solution for Qt 4.8 (edit)
After some time of research I can suggest the following solution. You have to make a new class inheriting QMdiArea. Set its view mode to TabbedView to make the standart QTabBar to be constructed within QMdiArea. Then get all children and find QTabBar widget with QString(QObject::metaObject()->className()) == "QTabBar". Hide it. You will get a blank area above the document in TabbedView mode. Construct you custom tab bar and reparent it to your custom mdi area. Connect signals and slots that are fired and used when the sub windows and tabs are activated. You can have your custom tab bar as a class member of your custom mdi area.
If you have found this post useful please vote on it. Thanks.
Some code for example.
Looking for a standart QTabBar within a custom mdi area in its constructor:
m_pMdiAreaTabBar = NULL;
m_pMdiArea->setViewMode(QMdiArea::TabbedView);
QObjectList listChildren = m_pMdiArea->children();
for (QObjectList::Iterator i = listChildren.begin(); i != listChildren.end(); ++i)
{
if (QString((*i)->metaObject()->className()) == "QTabBar")
{
m_pMdiAreaTabBar = dynamic_cast<QTabBar*>(*i);
break;
}
}
Reparent:
m_pTabBar->setParent(m_pMdiArea);
Hiding:
if (m_pMdiAreaTabBar != 0) m_pMdiAreaTabBar->hide();
Signals & Slots used: QMdiArea::subWindowActivated(QMdiSubWindow*), QTabBar::currentChanged(int)