qt use widget crash - c++

I have a class :
class gameClientInteraction : public QMainWindow
with, in the .h :
private :
QTextEdit* console;
my constructor is like this :
gameClientInteraction::gameClientInteraction()
{
// Menus
QMenu *menuFichier = menuBar()->addMenu("&Jeu");
QAction *actionQuitter = new QAction("&Quitter", this);
menuFichier->addAction(actionQuitter);
connect(actionQuitter, SIGNAL(triggered()), qApp, SLOT(quit()));
// View
QGraphicsView *theGraphicsView = new QGraphicsView(this);
theGraphicsView->setFixedSize(605,605);
QTextEdit* console = new QTextEdit(this);
console->setGeometry(0,625,600,100);
console->setReadOnly(true);
console->append("Bienvenue !");
setCentralWidget(theGraphicsView);
//Scene
theGraphicsView->setScene(m.afficheMap());//afficheMap give me a QGraphicsScene*
}
I have this function that crash my program when I launch it (it 's okay when I comment the instruction).
void gameClientInteraction::msgConsole(QString msg){
console->append(msg);
}
So why is it crashing with this instruction?

You've hidden the class member variable console in your constructor by declaring a local pointer with the same name. In other words, this:
QTextEdit* console = new QTextEdit(this);
should be this:
console = new QTextEdit(this);
As an alternative, consider using an initialization list:
gameClientInteraction::gameClientInteraction() : console(new QTextEdit(this))
{
// constructor code goes here
console->setGeometry(0,625,600,100);
console->setReadOnly(true);
console->append("Bienvenue !");
}

Related

Access QT Widget child members from QT Widget Object Instance

Consider this QWidget initialized as:
QWidget *Logger;
Logger = new QWidget();
QPushButton *btn;
btn= new QPushButton(Logger);
btn->setObjectName(QStringLiteral("pushButton"));
Logger->show();
It display the Logger with a button with text pushButton.
Now Later if i want to access pushButton, i do it like this:
QPushButton *pushButton = Logger->findChild<QPushButton *>("pushButton");
pushButton->setText("NEW BUTTON");
I want to know is there a possibility to access directly this pushButton from Logger??Something like:
Logger->btn ...
I tried but it does not work. I have Widgets defined like this with many child objects and i wonder is this the only way to access them at run time??
EDIT: #drescherjm, So something along these lines you mean:
class MyWidget : QWidget
{
public:
QPushButton *pushButton;
MyWidget(){
pushButton = new QPushButton(this);
}
};
MyWidget *w = new MyWidget();
w->pushButton->setText("XYZ");
And is it worth it to create so many classes?? for small redundant tasks?
It won't work the way that you are expecting it to work. Use btn as long as it is in scope.
If you are creating btn somewhere locally, but your use-case demands you to use it in different places across your code, then you need to reconsider your design and make the QPushButton part of a class member.
Something of this sort :
#include <QPushButton>
class SampleWidget : public QWidget
{
public :
SampleWidget( QWidget * inParent );
// public methods to change the properties of the QPushButton go here.
void SetButtonText( QString const & inString );
bool IsButtonChecked();
private :
QPushButton *mSampleButton;
};
And in the implementation :
SampleWidget::SampleWidget(QWidget *parent)
:
mSampleButton( new QPushButton( parent ) )
{
// connect( mSampleButton,......... ); Connection to slot
}
void SampleWidget::SetButtonText( QString const & inString )
{
mSampleButton->setText( inString );
}
bool
SampleWidget::IsButtonChecked()
{
return mSampleButton->isChecked();
}
The question was not very clear on what you exactly want, but it seems like you are struggling to understand how to alter the attributes of a push button if it is a private member of a class and the above example will help you with that.

How to hide a temporary search bar?

I have a window that contains a browser. Up is a toolbar. In the bottom of the window is a search bar.
Search bar has a close button [x].
When the user clicks the close button I want the bar to disappear.
I want the bar only appear when user press CTRL + F. I tried to connect the close butoon with .hide() command, but application crashes. I need help.
.cpp
DocumentationWin::DocumentationWin (QWidget * parent){
docs = new QTextBrowser( this );
//Prepare toolbar
toolbar = new QToolBar( this );
//add stuff to toolbar
//Prepare footer bar
searchlabel = new QLabel(tr("Find in page:"),this);
resultslabel = new QLabel("",this);
searchinput = new QLineEdit();
findprev = new QToolButton(this);
findprev->setArrowType(Qt::UpArrow);
connect(findprev, SIGNAL(clicked()), this, SLOT (clickFindPrev()));
findnext = new QToolButton(this);
findnext->setArrowType(Qt::DownArrow);
connect(findnext, SIGNAL(clicked()), this, SLOT (clickFindNext()));
QStyle *style = qApp->style();
QIcon closeIcon = style->standardIcon(QStyle::SP_TitleBarCloseButton);
QPushButton *closeButton = new QPushButton(this);
closeButton->setIcon(closeIcon);
closeButton->setFlat(true);
connect(closeButton, SIGNAL(clicked()), this, SLOT (clickCloseFind()));
QWidget *bottom = new QWidget;
QHBoxLayout *footer = new QHBoxLayout();
casecheckbox = new QCheckBox(tr("Case sensitive"),this);
footer->setContentsMargins(5,5,5,5);
footer->addWidget(searchlabel);
footer->addSpacing(3);
footer->addWidget(searchinput);
footer->addWidget(findprev);
footer->addWidget(findnext);
footer->addSpacing(10);
footer->addWidget(casecheckbox);
footer->addSpacing(10);
footer->addWidget(resultslabel);
footer->addStretch(1);
footer->addWidget(closeButton);
bottom->setLayout(footer);
//Prepare main layout
layout = new QVBoxLayout;
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(0);
layout->addWidget(toolbar);
layout->addWidget(docs);
layout->addWidget(bottom);
this->setLayout(layout);
this->show();
}
void DocumentationWin::clickCloseFind(){
bottom->hide();
}
.h
class DocumentationWin : public QDialog
{
Q_OBJECT
public:
DocumentationWin(QWidget * parent);
protected:
virtual void keyPressEvent(QKeyEvent *);
private slots:
void clickCloseFind();
private:
QVBoxLayout* layout;
QToolBar* toolbar;
QTextBrowser* docs;
QBoxLayout* footer;
QLabel *searchlabel;
QLabel *resultslabel;
QLineEdit *searchinput;
QToolButton *findprev;
QToolButton *findnext;
QCheckBox *casecheckbox;
QWidget *bottom;
QPushButton *closeButton;
};
Ahh, the classic case of local variables hiding the members. There have been quite a few identical questions on SO about this. This is wrong:
QWidget *bottom = new QWidget;
You want:
bottom = new QWidget;
You'll run into these problems always because you dynamically allocate all the widgets - that's completely unnecessary.
Suggestions:
Hold the child widgets and layouts by value, don't dynamically allocate them.
Don't pass a parent to widgets that are managed by a layout. Every widget that is laid out will be automatically parented.
Don't redundantly call setLayout. A QLayout takes the widget to lay its children on as a constructor argument.
QWidget::hide() is a slot.
Many widgets take the text as a constructor argument.
If you don't have any arguments to pass to the constructor in a new expression, you can drop the parentheses (but we try to avoid these anyway):
searchinput = new QLineEdit; // not QLineEdit();
Widgets shouldn't usually show() themselves upon construction. No Qt widget does that. It's up to the widget's user to do it.
C++ overloads a method call syntax with construction syntax. To differentiate the two, prefer uniform initialization (Type{arg0, arg1, ...}) over old syntax that used ().
Here's how your code can look when you're using C++11. This compiles with either Qt 4 or Qt 5. If you don't target Qt 4, you should be using the new connect syntax, though.
As you can see, there isn't a single explicit dynamic allocation - that's how quite a bit of C++11 code will look, when the used types are sane.
// https://github.com/KubaO/stackoverflown/tree/master/questions/find-hide-38082794
#include <QtGui>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#endif
class DocumentationWin : public QDialog
{
Q_OBJECT
public:
explicit DocumentationWin(QWidget * parent = 0);
private:
QVBoxLayout layout{this};
QToolBar toolbar;
QTextBrowser docs;
QWidget bottom;
QHBoxLayout footer{&bottom};
QLabel searchlabel{tr("Find in page:")};
QLabel resultslabel;
QLineEdit searchinput;
QToolButton findprev;
QToolButton findnext;
QCheckBox casecheckbox{tr("Case sensitive")};
QPushButton closeButton;
Q_SLOT void onFindPrev() {}
Q_SLOT void onFindNext() {}
};
DocumentationWin::DocumentationWin(QWidget * parent) : QDialog(parent) {
findprev.setArrowType(Qt::UpArrow);
connect(&findprev, SIGNAL(clicked()), this, SLOT(onFindPrev()));
findnext.setArrowType(Qt::DownArrow);
connect(&findnext, SIGNAL(clicked()), this, SLOT(onFindNext()));
auto style = qApp->style();
auto closeIcon = style->standardIcon(QStyle::SP_TitleBarCloseButton);
closeButton.setIcon(closeIcon);
closeButton.setFlat(true);
connect(&closeButton, SIGNAL(clicked(bool)), &bottom, SLOT(hide()));
footer.setContentsMargins(5,5,5,5);
footer.addWidget(&searchlabel);
footer.addSpacing(3);
footer.addWidget(&searchinput);
footer.addWidget(&findprev);
footer.addWidget(&findnext);
footer.addSpacing(10);
footer.addWidget(&casecheckbox);
footer.addSpacing(10);
footer.addWidget(&resultslabel);
footer.addStretch(1);
footer.addWidget(&closeButton);
layout.setContentsMargins(0,0,0,0);
layout.setSpacing(0);
layout.addWidget(&toolbar);
layout.addWidget(&docs);
layout.addWidget(&bottom);
}
int main(int argc, char ** argv) {
QApplication app{argc, argv};
DocumentationWin win;
win.show();
return app.exec();
}
#include "main.moc"

Qt4 application crash, segmentaton fault when click connected button

I've created a simple application with QGraphicsView and I have a problem with connected button.
There is a simple window with QGraphicsScene and one QPushButton and a function which should add a rectangle to my scene. Compilation is ok, it works and after I click this button application crash.
.h file:
class Canvas : public QWidget{
Q_OBJECT
public:
Canvas(QWidget *parent = 0);
private slots:
void addPoint();
private:
QGraphicsScene *scene;
QPushButton *btn;
};
.cpp file:
Canvas::Canvas(QWidget *parent)
: QWidget(parent)
{
QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->setSpacing(1);
QPushButton *btn = new QPushButton("test", this);
QGraphicsView *view = new QGraphicsView(this);
QGraphicsScene *scene = new QGraphicsScene(this);
view->setScene(scene);
vbox->addWidget(view);
vbox->addWidget(btn);
setLayout(vbox);
connect(btn, SIGNAL(clicked()), this, SLOT(addPoint()));
}
void Canvas::addPoint()
{
scene->addRect(100,0,80,100);
}
Also debuger said:
The inferior stopped because it received a signal from the Operating System.
Signal name : SIGSEGV
Signal meaning : Segmentation fault
And points this line:
{ return addRect(QRectF(x, y, w, h), pen, brush); }
What am I doing wrong? Thanks in advance.
The following statement in your constructor is a local variable definition and initialization:
QGraphicsScene *scene = new QGraphicsScene(this);
The actual scene member variable is never initialized and anything that tries to use this->scene will crash the application.
As you want to initialize the existing scene variable, you should omit the type in front of the variable:
scene = new QGraphicsScene(this);

Browser of file

I'm trying to develop a file browser in Qt and C++.
Opening a FileSystem can take a lot of memory. In that way, the best is to only open what is inside a folder when I click on it.
In my browser.h, I have declared the OnClick signal.
class Browser : public QTreeWidget
{
Q_OBJECT
public:
Browser(USBDevice dev, QWidget* parent = 0);
QTreeWidget(parent)
{
connect(this , SIGNAL(itemClicked(QTreeWidgetItem*,int)),this,
// SLOT(showDirectory(QTreeWidgetItem*,int)));
};
~Browser(){};
public slots:
void showDirectory(QTreeWidgetItem* item, int /*column*/)
{
...
}
};
QTreeWidget is failing to build saying :
error: function definition does not declare parameters - QTreeWidget(parent)
in the browser.cpp, I have wrote the code to create window, widget..
Browser::Browser(USBDevice dev, QWidget *parent) :
QTreeWidget(parent)
{
QMainWindow *window = new QMainWindow();
window->setWindowTitle(QString::fromUtf8("PULS"));
window->resize(400, 400);
QWidget *centralWidget = new QWidget(window);
QTreeWidget *MyTree = new QTreeWidget(centralWidget);
MyTree->setFixedSize(395,395);
}
//Set QTreeWidget Column Header
QTreeWidgetItem* headerItem = new QTreeWidgetItem();
headerItem->setText(0,QString("File Name"));
headerItem->setText(1,QString("Size (Bytes)"));
headerItem->setText(2,QString("Date"));
MyTree->setHeaderItem(headerItem);
I don't understand but How to manage connect ?
You've got a ; instead of a : before the initialiser list for your constructor:
Browser(USBDevice dev, QWidget* parent = 0); // <--- here
QTreeWidget(parent)
{
...
FWIW, I recommend putting the colon at the start of the line like this:
Browser(USBDevice dev, QWidget* parent = 0)
: QTreeWidget(parent)
{
...
That way it's much clearer how the second line relates to the first and third, and you'll get in the habit of editing the declaration when you go to make it a definition, avoiding the kind of problem you had.

Qt QObject::connect() function cannot be connected

I have the code like this:
class MyListView : public QListView
{
public:
MyListView();
~MyListView();
public slots:
void insertData();
void deleteData();
void showData();
private:
QStringListModel *model;
QListView *listView;
};
And the constructor is like:
MyListView :: MyListView()
{
QStringList data;
data << "Letter A" << "Letter B" << "Letter C";
model = new QStringListModel;
model->setStringList(data);
listView = new QListView;
listView->setModel(model);
/* the three buttons */
QPushButton *insertBtn = new QPushButton(QObject::tr("insert"),this);
QObject::connect(insertBtn,SIGNAL(clicked()),this,SLOT(insertData()));
QPushButton *deleteBtn = new QPushButton(QObject::tr("delete"),this);
QObject::connect(deleteBtn,SIGNAL(clicked()),this,SLOT(deleteData()));
QPushButton *showBtn = new QPushButton(QObject::tr("show"),this);
QObject::connect(showBtn,SIGNAL(clicked()),this,SLOT(showData()));
/* layout */
QHBoxLayout *btnLayout = new QHBoxLayout;
btnLayout->addWidget(insertBtn);
btnLayout->addWidget(deleteBtn);
btnLayout->addWidget(showBtn);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(listView);
mainLayout->addLayout(btnLayout);
setLayout(mainLayout);
}
So I want to connect the push button to the slot functions, but when I compile it, I got the error message as:
QObject::connect: No such slot QListView::insertData()
I think the problem comes from the connect function, in which, "this" is not the right pointer, any help? Thanks in advance.
You need to add the Q_OBJECT macro in your MyListView
From Qt API docs:
Notice that the Q_OBJECT macro is mandatory for any object that
implements signals, slots or properties. You also need to run the Meta
Object Compiler on the source file. We strongly recommend the use of
this macro in all subclasses of QObject regardless of whether or not
they actually use signals, slots and properties, since failure to do
so may lead certain functions to exhibit strange behavior.
So, it should be:
class MyListView : public QListView
{
Q_OBJECT
public:
...
}