Passing variable to promoted QWidget - qt

I have two classes:
-MainWindow
-MyWidget which is promoted in MainWindow.ui using QT Creator's design tab.
Both of the class .ui's are designed in design tab.
I try to pass variables to MyWidget from MainWindow without any success. Compiler doesn't give any errors, but variables are not passing. Is there any way to do this? MyWidget works well as long as I don't import MainWindow to it or import MyWidget to MainWindow. After import I can't control MyWidget's content by code. Any suggestions?
EDIT: Made a small example and added code to pastebin, so this post won't get bloated.
MainWindow.h
MainWindow.cpp
another links are in comments

Your class MainWindow does not need to a MyWidget attribute. MyWidget object is actually created by Ui::MainWindow object.
So, to access your MyWidget object (the one displayed on screen as part of MainWindow widget), use ui->widget (as widget is the name you gave the object in Qt Designer <widget class="MyWidget" name="widget" native="true"/>), instead of mw.
Modifying mw makes no sense because this instance of MyWidget is not used for GUI display.
You then have to change:
connect(this, SIGNAL(text(QString, QString)),&mw, SLOT(addText(QString,QString)));
into:
connect(this, SIGNAL(text(QString, QString)),ui->widget, SLOT(addText(QString,QString)));
Note: If MyWidget class needs parameters to be passed upon construction, you can remove the widgetinstanciation from your .ui file and create it locally using mw attribute of the MainWindow class as you did. But, then, to have this instance be shown on screen, you must add it to the layout of your MainWindow, like this (for example): ui->horizontalLayout->addWidget( &mw );

Related

How can i change QMainWindow to QDialog

I am new in Qt. I have made a project in Qt.
Now I need to change the QMainWindow into QDialog.
How can I do this without deleting all my project?
If a change the base mainwindow into QDialog, it is necessary to make a new window for being main?
Depending on if you have a .ui file or not.
If so, you could edit the .ui and change the line
<widget class="QMainWindow" name="MainWindow">
To
<widget class="QDialog" name="MainWindow">
Also, think about if classes like QMenuBar, QToolBar and QStatusBar are necessary in your project. Qt Designer puts them in the .ui file by default and because they are used by QMainWindow.
After that, you should change the base class for your MainWindow. You should have something like this:
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
So you need change QMainWindow by QDialog.
#include <QDialog>
namespace Ui {
class MainWindow;
}
class MainWindow : public QDialog
{
If you don't have a .ui file, the first step is no necessary (obviously :))
Of course, you will need to check if you are using any QMainWindow method which is not implemented by QDialog in order to avoid compilation error and lack of functionality.
You can freely use any type of QWidget as main. The main window is whatever you decide it to be, typically the one you create and show in your main() function. So you can freely change your base class to QDialog and it will probably just work.
However, if you used Qt Designer (either directly or through Qt Creator) to create the .ui file containing all the widgets rather than coding the interface by hand, and you don't want to go through that hassle again, it can be a bit tricky.
One way is to create a new QDialog and then simply copy-paste the designed window contents to the new window. This is the easiest approach, but you may lose some properties that you set in the designer because not everything is copied.
A more tricky, but also more powerful way is to edit the created .ui file by hand. It's just a simple XML file, after all. Look for the class attribute and change class="QMainWindow" to class="QDialog". You should also look for properties and check whether these properties are defined in QDialog by looking at the docs. If they are QMainWindow-specific, then just delete them carefully.
Of course, you should back up your project (or commit it to the source control system) prior to playing around with XML because you may screw up something so that the designed will simply obliterate parts of your files it can't parse.

Qt paint on a widget created by QT Designer

How can I paint on a widget without overwriting the paintEvent.
I want to paint on a widget which is inside another one generated by Qt Designer , so i can't overwrite its paintEvent.
I tried to paint directly like this :
QPainter *painter= new QPainter(ui->drawArea);
painter.drawLine(50,50,50,150);
painter.close();
but Qt tell me that the QPainDevice is 0 or something like this,
I tried the same example by creating the painter then call the begin() method with the QPaintDevice (the widget) but same problem.
Qt version : 4.8.6.
Using custom widgets in Designer is not an issue. In Designer, add your widget as any other QWidget or QPushButton, depending which has the closest inheritance. Then with right click menu select Promote to ..., add your MyWidget.h and then promote the widget to MyWidget with reimplemented paintEvent(). Read more:
http://doc-snapshots.qt.io/4.8/designer-using-custom-widgets.html#promoting-widgets

Opening a Widget created in Designer, from a Main Window

I’ve created 2 .ui files, one is a main window, the other a widget. Designer generates the 2 .header files each with QT_BEGIN_NAMESPACE around the class declaration.
The problem is, what works in opening my main window, does not work in opening the second widget window.
To display my main window, I created a class that inherits from my .ui file:
class myWindow: public QMainWindow, private Ui::uiClassWindow
setupUi(this);
That opens fine, so then to open the second widget window, I declare a generic widget object and then save it with a pointer to my Widget Ui header file:
QWidget newWidget;
setupUi(newWidget)
But setupUi resolves to my Main Window header file… How do I tell it to use the Widget’s setupUi?
Is there a better way to go about this?
Up to my knowledge, for setupUi function is defined in Ui namespace. You need to give scope (Ui) for other widget too.
The setupUi() method is created by uic from your UI file, and it's different for each compiled UI.
In your myWindow, you inherit from Ui::uiClassWindow and can use its setupUi() method without qualification. You'll need an instance of a different UI class for your newWidget:
auto widget_ui = new Ui::myWidget;
QWidget newWidget;
widget_ui->setupUi(newWidget)
You could delete the widget_ui immediately if you wanted - but usually, you'll need to keep it in order to access the children it has now created in newWidget.

Qt: Best mechanism to capture and pass signals

I have a class extending QWidget class and this class uses a Ui class generated by QtDesigner. Something like following:
class MyWidget : public QWidget
{
signals:
void pushButtonClicked();
// ....
private:
Ui::MyUi ui;
}
MyWidget::MyWidget()
{
ui = new Ui::MyUi();
ui->setupUi(this);
}
Now lets suppose there is a QPushButton * pushButton field inside Ui::MyUi. The UI for this widget has no complex business logic.
Now it is required that whenever pushButton is clicked this widget should emit a signal (lets call it pushButtonClicked(). Now the only way I can imagine this to be achieved is to:
connect clicked() signal of pushButton object to a local slot and emit signal pushButtonClicked()from there.
Install MyWidget as mouseEventFilter for pushButton and handle it inside MyWidget::mouseClickedEvent
Are there other options? Like somehow letting Qt framework to use 'MyWidget::pushButtonClicked()' instead of pushButton->clicked()
In the project I have many scenarios like this where such signal passing is needed from the wrapper classes like MyWidget, which wrap/abstract the UI by aggregation or inheritance. In general which is considered the best approach for better design, code reuse esp. when the project is at nascent stage and it is not known which of these UIs might need complex business logic in the future.
Please note that extending QPushButton is not an option.
You can connect signals directly =)
connect(pushButton , SIGNAL(clicked()), this, SIGNAL(pushButtonClicked()));

how to create & call slot in other class than MainWindow?

Currently Im using QT Creator which created UI file for view and I'm a QT starter.
There is a part I am curious is that how can i create another Class for, let say a GraphicView, so that I can send signal and slot to that class instead of the main form?
Side Question: why I can't edit Singal and Slot in other place than MainWindow in Edit Signal/Slot Mode? (the edit button is not activated if it's not MainWindow, so i have to use those default Signal) Let say i need to create a ToggleFullScreen() but the edit is gray out, how do I do it?
Adam is right.
But there are several ways to use a UI file in your application.
Have a look at http://qt.nokia.com/doc/4.5/designer-using-a-ui-file.html
For signal-slot specific question : see the link in Adam answer.
But, in summary, if you declare the Q_OBJECT macro in yours classes, you can communicate between those by signal-slot mechanism !
Signals and Slots
You have to create a derived class that inherits from QMainWindow if you want to add new signals or slots.

Resources