QT QTextEdit setText crashes - c++

I've created a qt widgets application. Using the design mode I've created a QTextEdit and indicated that in the header file:
...
QT_BEGIN_NAMESPACE
class QAction;
class QMenu;
class QTextEdit;
QT_END_NAMESPACE
...
private:
Ui::MainWindow *ui;
QTextEdit *textEdit_2;
};
There is also a slot which is triggered by pushing a button. What it has to do is to insert some text into textEdit_2 after the button is pushed, still the program crashes.
In mainwindow.cpp:
void MainWindow::on_action_4_triggered()
{
textEdit_2->setText("text");
}
I've also tried
textEdit_2->setText(QString("text"));
which anyway doesn't work. What's the problem?

textEdit_2->setText("text");
The problem is that you are trying to ignore the actual text widget created in QtDesigner and invent another as a class member. This is not going to fly as you seem to want it.
In order to reuse the text widget from the UI that you created with the graphical tool, you would need to reuse the ui object as follows:
ui->textEdit_2->setText("text");
Please also note that you do not need to construct QString explicitly like this:
textEdit_2->setText(QString("text"));
This will be all automatic for you.

Related

Qt5 ui, multiple windows: how can I access the Ui objects in Window 2 from Window 1

I know this is very clunky and I'm probably doing a lot of wrong things but so far everything I saw on the net gives back the same errors: invalid use of non-static data member ui.
So in the MainWindow, I have a comboBox named hometeam, and I want to display the currentText on a Qlabel named label which is on another Form Class called Dialog
I figured they're both private members so I added friend class MainWindow and friend class dialog in the respective headers (I know this is pretty wrong but it's the last thing I tried), I included the "ui_mainwindow" and "ui_dialog" in the .cpp files, and here's the bit of code I'm trying:
ui->label->setText(MainWindow::ui->hometeam->currentTex());
Keep in mind that I don't want a QDialog, the second window will do a lot more than a display, I just want to access the objects from a different window. Slots and signals give the same error.
Thanks !
I think the proper way to do that, is to add a function to your MainWindow class:
QString hometeamText() const
{
return ui->hometeam->currentTex();
}
This way you can access the information you need without violating encapsulation rules, but you need an instance of MainWindow to do it, and sure must keep a pointer to it in your Dialog class:
class Dialog
{
private:
MainWindow * mainwindow;
public:
void setMainWindow(MainWindow * w) { mainWindow = w; }
then somewhere (e.g. in main) you can do something like:
MainWindow mainwindow;
Dialog dialog;
dialog.setMainWindow(&mainWindow);
and from inside your Dialog class, wherever you need it:
ui->label->setText(window->hometeamText());

Adapt Qt window form to prebuilt QWindow

I'm testing a project I've downloaded that doesn't have a "mainwindow.ui" but the main window is created programmatically inheriting QWindow instead.
OpenGLWindow::OpenGLWindow(QScreen* screen ): QWindow(screen)
It works properly but of course adding new elements on this window is not as quick as it would be using the Qt designer. Therefore I was wondering if there is a way, after creating a new form with the Qt designer, to promote the new window to this existing OpenGLWindow so that I can view its content in the "newwindow.ui". I hope this makes sense.
I'm not completely sure, but this general idea should work, assuming the window class you created is named NewWindow:
class OpenGLWindow : public QWindow {
Ui::NewWindow *ui; // Add this variable
/* rest of class */
}
#include <ui_newwindow.h>
OpenGLWindow::OpenGLWindow(QScreen* screen): QWindow(screen), ui(new Ui::NewWindow) {
ui->setupUi(this);
/* rest of constructor */
}
And then don't forget to delete ui in the destructor.

Multiple QWidets into one QMainWindow

I am currently learing Qt, and I am stuck on the problem of using multiple QWidgets and one QMainWindow.
I have setup a project which contains 2 QWidgets and one QMainWindow. This is my idea of using it: design both QWidgets as needed, add them to the mainwindow object, connect the buttons to the correct slots and switch the centerwidget when needed. So I started off with one QMainWindow and then added two QWidgets, including the cpp file, the h file and the ui file. On both QWidgets I added one QPushButton, and called it pushButtonConvert.
Then I went to the cpp file attached to the QMainWindow (mainwindow.cpp) and did the following:
EpochToHuman * epochToHuman = new EpochToHuman();
HumanToEpoch * humanToEpoch = new HumanToEpoch();
Up until this point everything is fine. Now I want to connect the buttons to slots in the mainwindow object, but I can not find the buttons. epochToHuman->pushButtonConvert does not seem to exist, and I can not find any other way to get to the buttons. So am I thinking in a way that is not correct, according to Qt or am I missing something?
Another try at clarifying what I want:
I want to use the elements in a QWidget in QMainWindows' cpp file. I want to be able to do things like this:
//In object MainWindow.cpp
QWidget * a = new QWidget
//Let's say a is a custom widget with a label in it. This label is called Label
a->Label->setText("Hello, World!");
//This gives an error because a does not have a member called Label
//How can I change the text on the label of a?
//And I think if I will be able to change the text of this label, I will also be able to dance around with buttons as needed.
You can connect the pushButtonConvert button to MainWindow::convertFromEpochToHuman in the constructor of MainWindow, with:
connect(epochToHuman->ui->pushButtonConvert, SIGNAL(clicked(bool)), this, SLOT(convertFromEpochToHuman()));
You'll need to make the ui member public first, like you have done for HumanToEpoch.
You should move the declaration of your widgets into MainWindow.h:
// ...
private:
Ui::MainWindow *ui;
EpochToHuman * epochToHuman;
HumanToEpoch * humanToEpoch;
// ...
and initialise them like this:
epochToHuman = new EpochToHuman(this);
humanToEpoch = new HumanToEpoch(this);

Why do we pass "this" pointer to setupUi function?

I'm fairly new in QT. Taking below fairly simply explain from qt docs :
class CalculatorForm : public QWidget
{
Q_OBJECT
public:
CalculatorForm(QWidget *parent = 0);
private slots:
void on_inputSpinBox1_valueChanged(int value); //why is that slots are private?
private:
Ui::CalculatorForm ui;
};
and implementation of constructor
CalculatorForm::CalculatorForm(QWidget *parent)
: QWidget(parent) {
ui.setupUi(this); // <-- Question below
}
Q: I was wondering why do we pass this pointer to setupUi function?, what does it do ?
So that the dialog will have the caller as parent, so that eg when the parent is closed the dialog can be closed automatically. Generally all gui elements have a pointer to their parent.
private slots:
void on_inputSpinBox1_valueChanged(int value); //why is that slots are private?
These are auto generated slots which exactly match the naming of the gui elments in QtDesigner. They are only meant to do the direct hookup to those gui elements and so should be dealt with in this class. If these signals were extended to other classes then any change in the gui would require changing a lot of other code which doesn't need to know details of the gui.
In the handler slot for the specific gui element you can then emit another more general signal to the rest of the app.
The only widget that setupUi doesn't create is the widget at the top of the hierarchy in the ui file, and as the Ui::CalculatorForm class instance doesn't know the widget it has to fill, it (this) has to be passed explicitly to the class at some point.
this or any other widget you would pass to it, is used as the parent to all other subwidgets. For example, you could fill a widget without inheritance like this:
QWidget *widget = new QWidget;
Ui::CalculatorForm *ui = new Ui::CalculatorForm;
ui->setupUi(widget);
widget->show();
But really, it would be easier to understand if you read the content of the uic generated file (probably named ui_calculatorform.h).
setupUi creates the instances of widgets (QLabel, QTextEdit and so on). The [user interface compiler] (http://qt-project.org/doc/qt-4.8/uic.html) gets information for you from the .UI form and generates widget-creation code in the generated moc source files.
The manual way of creating widgets without using the Qt Designer or a UI file would be like so:
QWidget* pWidget = new QWidget(this);
I think it is to add the caller widget to the layout of this UI.
This widget will be the toplevel widget.
Martin Beckett answer might be correct as well, as what he described is a common behavior in Qt (cf the 'parent' argument in most of widget's derived class constructor)
Note that you have alternative ways how designer can auto-generate code.
In this case you have a separate 'UI' class for this code which is not QObject so it also is not a QWidget.
Auto generated code needs information about parent widget and to make auto-conections of slots and signals so this is why you have to pass this.
This pater is less intrusive then other pasterns (that is why it is default). You can also try alternative patters (check Qt Creator Designer options), but I recommend you to see what is generated by designer tools in default settings.

Qt doesn't display child widget

How can i access ui files of children of a class. Lets say MainWindow class has twoa child dialog. I want to access LINEEDIT of dialog so that i can take text from there. Similarly how can i access ui files of parent inside child class in QT. Note: I havn't inherited any thing from Parent class.
I have writen the following code, in order to display a dialog but it won't show!
void MainWindow::displaydialog()
{
ItemDialog dialog= new ItemDialog(this);
dialog->show(); // it is not displaying the dialog
}
and how can i access the ui widgets like check whether ListWidget item has been selected or not.
Here is the code of itemdialog,
#include "itemdialog.h"
#include "ui_itemdialog.h"
#include "mainwindow.h"
ItemDialog::ItemDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::ItemDialog)
{
ui->setupUi(this);
setWindowTitle("Status Dialog");
setFixedSize(QWidget::sizeHint());
}
ItemDialog::~ItemDialog()
{
delete ui;
}
void ItemDialog::on_pushButton_clicked()
{
MainWindow obj;
obj.okbuttonclicked(ui->lineEdit->text());
}
Please review an example such as this: http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
It explains how to use the ui files that you generate from Qt Designer. You shouldn't really think of them as "ui files" in the sense of accessing them on the widgets in your class. The idea is that you include them, and then use their setupUi() function to apply them to your given class. At that point, everything you created in qt designer, and that is in that ui file, is now a member of your class. They can be accessed via the naming you used in qt designer.
As for why your dialog isn't showing...I don't know because you only included 3 lines of code as an example. Theoretically it should show if Mydialog was properly set up. You could just try changing it to a QDialog to make sure you didn't do anything wrong with your custom class.
It depends what you want that dialog for. Either it's a modal dialog - some kind of a information display or retrival that blocks the function of your program until user reacts, or it's somekind of toolbox or similar, in which case you probably should not use QDialog.
If a modal dialog with a line edits and/or additional features is what you want, you should read up on QDialog in the doc. See the exec() function. Basic usage would go like this:
void MainWindow::displaydialog()
{
ItemDialog *dialog = new ItemDialog();
if (dialog->exec() == someApropriateReturnStatus)
{
QString somevalue = dialog->someValue();
int dialog->someOtherValue();
//do something with the value
}
delete dialog;
}
The point is that the ItemDialog class handles the UI internally and implements the getter functions accordingly, you should not (in most typical cases) access it's UI from outside.
If a simple line edit is all you want, you'd be better off using one of the standard dialogs already implemented in Qt, have a look at the Standard Dialogs Example