setCentralWidget not declared in scope - qt

#include <QtGui>
#include <QWidget>
#include "notepad.h"
notepad::notepad()
{
textField = new QTextEdit;
setCentralWidget(textField);
setWindowTitle(tr("The building of a notepad...."));
}
This is a file of one of my Qt project. There is some error with the setCentralWidget part. The error is that it is not declared in the scope. But I have included the QWidget class under which it gets included. What is the mistake?

setCentralWidget is a method on QMainWindow. It is not a top-level function. It would only be in scope here if your notepad class derives from QMainWindow, which I guess it must not.

Like others have said, setCentralWidget(..) is only a member of QMainWindow. I think the behavior you are looking for can be achieved by adding a layout to your QWidget and then adding your QTextEdit to the layout. I would suggest a QPlainTextEdit as it is setup for editing multiple lines of a text document. QTextEdit is usually used for single line input. Here's some sample code:
notepad::notepad()
{
QVBoxLayout *layout = new QVBoxLayout();
QPlainTextEdit *textBox = new QPlainTextEdit();
layout->addWidget(textBox);
this->setLayout(layout);
setWindowTitle(tr("The building of a notepad...."));
}
The layout can be a QVBoxLayout, QHBoxLayout, QGridLayout, etc. It all depends on what you want to achieve with the layout of the form. You can also add to your existing layout by using this->addWidget(QWidget*) instead of using a newly created layout. I hope this helps.

Related

SIGSEGV when adding widget in Qt

I implemented example (chapter 2) from "Mastering Qt 5" book but the code crashes when adding widget to centralWidget's layout:
ui->centralWidget->layout()->addWidget(&mCpuWidget)
I suspect that the centralWidget does not have layout, hence it crashes but I don't know how to fix that?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
mCpuWidget(this)
{
ui->setupUi(this);
SysInfo::instance().init();
ui->centralWidget->layout()->addWidget(&mCpuWidget);
}
Here are two more classes which might help figure out the problem. Some of you might have the book too with all of the code (hence I mentioned it).
CpuWidget::CpuWidget(QWidget* parent):
SysInfoWidget(parent),
mSeries (new QPieSeries (this))
{
mSeries->setHoleSize(0.35);
mSeries->append("CPU Load", 30.0);
mSeries->append("CPU Free", 70.0);
QChart* chart = chartView().chart();
chart->addSeries(mSeries);
chart->setTitle("CPU Average Load");
}
This class creates and sets layout (QVBoxLayout)
SysInfoWidget::SysInfoWidget(QWidget *parent, int startDelayMs, int updateSeriesDelayMs) :
QWidget(parent),
mChartView(this)
{
mRefreshTimer.setInterval(updateSeriesDelayMs);
connect(&mRefreshTimer, &QTimer::timeout,
this, &SysInfoWidget::updateSeries);
QTimer::singleShot(startDelayMs,
[this] {mRefreshTimer.start();});
mChartView.setRenderHint(QPainter::Antialiasing);
mChartView.chart()->legend()->setVisible(false);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(&mChartView);
setLayout(layout);
}
I'm the co-author of the book "Mastering Qt 5" !
I guess your suspicion about the layout is correct:
ui->centralWidget->layout()->addWidget(&mCpuWidget);
Without any layout defined the returned item is null so you can't call the method layout().
If you have some errors during your learning you should refer to the final source code hosted on github here: https://github.com/PacktPublishing/Mastering-Qt-5
Take a look to the the file "Mastering-Qt-5/Chapter_02/MainWindow.ui":
<ui version="4.0">
...
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout"/>
</widget>
...
</ui>
As you can see for this project, a horizontalLayout of type QHBoxLayout is defined in the centralWidget. You can easily edit a ".ui" file with a text editor from Qt Creator with the following steps:
Right-click on "MainWindow.ui" in the Project hierarchy view
Select "Open-With"
Finally "Plain text editor"
Select "Form editor" when you want to come back to the WYSIWYG editor.
As suggested in other answers, the way to do it from C++ with the following line is also correct:
ui->centralWidget->setLayout(new QHBoxLayout());
Thank you for highlighting the lack of information about the layout here. I created an issue to add an errata about this topic.
Unless I have missed something in the code you have provided you haven't actually set your central widget. By default calling QMainWindow::centralWidget() returns a NULL pointer. You need to first call QMainWindow::setCentralWidget(QWidget* yourCentralWidget) before you call it. And yes, you also need to add a layout to it if you want to use layout()->addWidget(...). You can create an instance of a generic QWidget, set its layout, set is a central widget and then work with it.
You can fix your problem either by adding a layout in C++:
ui->setupUi(this);
SysInfo::instance().init();
ui->centralWidget->setLayout(new QVBoxLayout()); // Or any other layout class
ui->centralWidget->layout()->addWidget(&mCpuWidget);
Or in the UI Designer by using those buttons:
Note that for the buttons to be active you need to have at least 1 widget in your central widget and then select your central widget. You can then write:
ui->setupUi(this);
SysInfo::instance().init();
// One way
ui->centralWidget->layout()->addWidget(&mCpuWidget);
// Another way
ui->layout->addWidget(&mCpuWidget);
Finally you could also move your CpuWidget to the ui file using the "Promote to..." option in the contextual menu. In this case you would not need mCpuWidget but you could access it using something like ui->cpuWidget.
For more info read the Qt Designer manual:
Using Layouts in Qt Designer
Using Custom Widgets with Qt Designer

QFrame : create mousePressEvent

actually i'm trying to get a mousePressEvent for a QFrame in QT 5 (VS2010 with Qt-Addin). Saw so many suggestons here and on other forums, but newer got it to work, or i didnt understood the princip. Also looked at the scribble example, with no luck
How can i get the mousePressEvent for a QFrame? Do i have to create a class that is inheriting from a QFrame and then initialize this frame on my own in the main()-function? isnt there a solution that i can bind it to the Qt-Designer?
tried multiple things, mostly saw something like this:
protected:
void TestQtFormsApplication::mousePressEvent(QMouseEvent *qevent)
{
if (qevent->button() == Qt::LeftButton)
{
this->close();
}
};
with this i ever got the error C2027: use of undefined type 'QMouseEvent'
Subclass QFrame and reimplement mousePressEvent(..) much like you have in your example. Remember to accept() the event to stop it propagating to the parent widget. Your error is because QMouseEvent is only forward declared in the QWidget header file, just include it yourself.
If you want to use your subclass in Qt Designer, just use a QFrame and the 'Promote' it to your subclass (docs).

Connecting a setValue slot of a custom slider so that it is called when changing the value in QSpinBox?

I am creating a custom slider class using QAbstractSlider as base class. In the main function I have tried connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int))) but it is not working.
The connection should work.
Make sure that you have used the Q_OBJECT macro in your class definition. Also in the main.cpp do the following:
Add the following include:
#include <QErrorMessage>
and add the following line of code
QErrorMessage::qtHandler();
If there is any problem with Singal /Slot connections a qt dialog will popup.

Using Qt Creator (with Qwt), really basic stuff

I'm trying to make a Qt program using Qt Creator and Qwt for plotting. I've never used Qt Creator before. I've created a MainWindow and added a Qwtplot widget there (object name: qwtPlot). The widget shows up in the program when I compile and run it. But theres no mention of the qwtPlot object anywhere in the (autogenerated) code so I assume it is being added at compile time from the .ui xml file (or something).
My question is that... how do I modify/change the qwtPlot object? Or where should I place the code?
I'm having a hard time articulating my question but the question basically is "How do I do anything with the qwtPlot widget which is created (graphically) with Qtcreator?". I've checked some tutorials but in the tutorials they add the widgets manually in the code, but I'd like to use Qt Creator (because my UI will be fairly complicated). This whole Qt Creator is pretty confusing...
A typical solution is to use multiple inheritance or contain the UI component as a private member. Qt explains the process on their web site:
Using a Designer UI File in Your Application
For a main window, most of this is auto-generated for you (on my version, at least ... 2.0.1)
You should have (or create) a mainwindow.h file that contains a member of type Ui::MainWindow.
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
Your mainwindow.cpp should initialize it properly, and then you can get to the auto-generated members through the private ui member.
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow) {
ui->setupUi(this);
ui->myControl->setProperty(...);
}
MainWindow::~MainWindow() {
delete ui;
}
If you use the multiple-inheritance method, you can access the members directly.

Accessing the child UI elements in a Qt UI

I have defined a UI (let's call it myUI) using the Qt designer, and using it in my applications. I need to access all the sub-widgets (QToolButtons) in myUI. I want to get all the subwidgets as a QObjectList.
Is there any way to do this?
The QObject::children() doesn't work here because the Qt UI Compiler, when converting the .ui file to a C++ class, doesn't define the ui_myUI class as a subclass of any QObject derived class. Is there any way to force it to do this, and then use the children() function?
Thanks.
Call children() on the top level widget instance.
Assuming your top level widget is called 'tlWidget':
myUI->tlWidget->children()
Usually what happens is that you either inherit from the UI class or you have it as a member and invoke it's setupUi method, sending this as the parameter. The default in Qt Creator/Designer is to have it as a member, named ui.
You can use this member to access any widgets defined in your form.
You might find this interesting:
Designer: Using a .ui file in your application
How do you use your UI ?
(a) something like:
class MyWidget: public QWidget, protected myUI
{
//...
};
(b) or rather something like:
class MyWidget: public QWidget
{
protected:
myUI ui;
};
The Solution is similar for both cases, assumed that you call setupUi(this) or ui.setupUi(this) in the constructor of MyWidget
setupUi(QWidget* p) registers every widget of the UI as children of QWidget p,
so you can easily access them by calling the children() function of p:
this->children(); //"this" refers to an object of MyWidget

Resources