send reference qplaintextedit to C++ constructor class - c++

I need to send reference a QPlainTextEdit to my C++ class Analizador for add lines to QPlainTextEdit from my class. I add the include <QPlainTextEdit> to the class, create the QPlainTextEdit from the graphic interface and call the constructor function just like that
Analizador *anal=new Analizador(ui->textProgres);
the constructor function is:
Analizador(QPlainTextEdit* text);
the compiler throw the error :
mainwindow.cpp:23: error: undefined reference to
`Analizador::Analizador(QPlainTextEdit*)'
so I guess the error is because I'm not sending a pointer to the constructor function but I don't know how to access the pointers of QPlainTextEdit
PS. I'm new in Qt and C++

In this case, compiler complains that it cannot find the definition of Analizador constructor when it tries to link your application.
Make sure you have written the definition of Analizador::Analizador(QPlainTextEdit*) constructor.
If you have written the constructor but still you gets this issue, The cpp file where your constructor exists may not have got compiled. If you are using QtCreator, try Build -> Run QMake and then Build -> Rebuild All

You can try this workaround.
#ifndef ANALIZADOR_H
#define ANALIZADOR_H
#include <QPlainTextEdit>
class Analizador
{
public:
Analizador(QPlainTextEdit *text)
{
plainTextEdit = text;
}
void addLines(QString line)
{
plainTextEdit->appendPlainText(line);
}
private:
QPlainTextEdit *plainTextEdit;
};
#endif // ANALIZADOR_H
And use this class like this.
analizador = new Analizador(ui->plainTextEdit);
analizador->addLines("Hello");
analizador->addLines("World");

Related

Is it possible to connect a slot or regular function from one class to a slot or regular function from another class? (QT)

To be specific to my problem I've been trying to connect a a slot from one class to a regular function of another class. I'm trying to do this so I can close the ui of one the main window from a dialog window. I tried everything I could possibly think of but it seems like every time I think of something to try the Qt compiler shuts me down by throwing some error or not working for no apparent reason such as when I did this
function(Ui::MainWindow *ui)
{
copy = ui; // copy is a pointer declared as Ui::MainWindow *copy in the dialog class
}
I tried this so I could close the main window from the copy pointer in the dialog class and although it compiled for that, it wouldn't compile when I tried to use it in another function of that class even though it was a class variable. After that I then realized that I should be able to connect the two functions from the main function. I wrote this
QObject::connect(&i, SIGNAL(on_passInput_returnPressed()), &w, SLOT(initalizer()));
The above compiles but when debugging I discovered it never gets executed and not sure why despite the fact that the SIGNAL on_passInput_returnPressed() is actually declared as slot in the class header. If that is the reason why it doesn't get executed how do I connect the slot from the dialog class to a regular function from the MainWindow class? There must be a way because I spent a day practically thinking about this non-stop and can't think of any other way given the nature of object scopes (in OOP) on top of the fact that the pointer thing I thought of didn't work.
Also I just now recreated the error from the pointer thing described above here it is.
error: invalid use of incomplete type 'class Ui::MainWindow'
copy->close();
^
Again this error is referring to trying to access the close function via the copy pointer from another function in the same class as the pointer assignment that worked in the other function. The copy pointer is declared as follows in the class header. Also in case you're wondering, yes, the pointer assignment written above does get executed. I checked via debugging.
private:
Ui::InitalPrompt *ui;
Ui::MainWindow *copy;
If you need more info just let me know what you need and I'll edit this post with it. I've obsessively tried so much I can think so much so that I've given up without further help due to how unforgiving Qt has been with me.
Also if there's a way of doing what I'm trying to do with the new Qt5 syntax of the connect function can you please give me the exact thing to type because despite looking into that new syntax myself I can't get it to compile for the life of me. (and yes I'm using Qt5) That's why the code above is written as old-fashion syntax.
Added the following as suggested to do so in a reply which is the class of the copy pointer.
#include "initalprompt.h"
#include "ui_initalprompt.h"
#include "mainwindow.h"
#include <QLineEdit>
#include <QCloseEvent>
#include <QMessageBox>
InitalPrompt::InitalPrompt(QWidget *parent) :
QDialog(parent),
ui(new Ui::InitalPrompt)
{
ui->setupUi(this);
}
InitalPrompt::~InitalPrompt()
{
delete ui;
}
void InitalPrompt::on_passInput_returnPressed()
{
pass = ui->passInput->text();
}
void InitalPrompt::reject()
{
QMessageBox::StandardButton resBtn = QMessageBox::Yes;
bool changes = false;
if (changes) {
resBtn = QMessageBox::question( this, "APP_NAME",
tr("Are you sure?\n"),
QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes,
QMessageBox::Yes);
}
if (resBtn == QMessageBox::Yes) {
QDialog::reject();
}
// the only issue is with the statment below don't know why
copy->close();
}
void InitalPrompt::catcher(Ui::MainWindow *ui)
{
copy = ui;
}
"Invalid use of incomplete type" means the compiler does not (yet) have a definition for the class when it reaches that line. In the header file that contains your copy pointer, include a forward declaration above the class declaration (the file would look something liek this):
#ifndef BLAH_BLAH_H
#define BLAH_BLAH_H
/*All of your normal #includes here*/
namespace Ui {
class InitialPrompt;
class MainWindow; //Note the forward declaration here
}
#include "mainwindow.h"
class BlahBlah
{
/*Class stuff here*/
private:
Ui::InitalPrompt *ui;
Ui::MainWindow *copy;
};
#endif //BLAH_BLAH_H
If you post the entirety of your class file that has the *copy, we can look further into it.
No, it is not possible. You can either:
call w->initalizer() directly from on_passInput_returnPressed() or
define a signal signal_on_passInput_returnPressed() in your ui class and emit that signal from on_passInput_returnPressed(). Then
QObject::connect(&i, SIGNAL(signal_on_passInput_returnPressed()), &w, SLOT(initalizer()));
should work.
For example:
class Whatever :
public QObject {
Q_OBJECT
void on_passInput_returnPressed();
signals:
void signal_on_passInput_returnPressed();
};
void Whatever::on_passInput_returnPressed() {
emit signal_on_passInput_returnPressed();
}

Qt: in a sub-class of QThread copy, the constructor is deleted by compiler

I am new to Qt and trying to use QThread in a console application.
environment:
Qt Creator 3.6.1; Based on Qt5.6.0 (MSVC2013 32bit); build on Mar 14 2016; revision d502727b2c
What I did is:
Create a derived class QtThread inherit the QThread class
Create an std container vector and initialize few threads
using std::for_each to start all thread
Here is my question
First, In the class QtThread I have to implement copy constructor function otherwise, I will have compile error
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0:657: error: C2280: 'QtThread::QtThread(const QtThread &)': attempting to reference a deleted function
The reason I have to implement copy constructor here, I think, is the base class QThread has destructor ~QThread(). So the compiler will mark copy ctr and move ctr as delete. The derived class does not inherit copy/move ctr from base class.
Three issues regarding this.
In the main function, I use emplace_back(). It seems the compiler is using copy constructor instead move.Why~ (the std::thread is move only, unable to be copied, so the QThread can be copied is a bit strange to me, or maybe I did some wrong but I did not realize)
I can not use keyword default to let the compiler generating a copy ctr for me, why
QtThread(const QtThread &in_thread) = default; // not working, still having compile error C2280
The copy constructor I implemented is not good, it just create another thread and copies the name of the thread, seems not good to me, but I cannot find a better solution. Any suggestions?
The base class QThread does not have a virtual destructor. That seems unusual to me. That means derived class can not implicitly call QThread's destructor. Or maybe I am not supposed to inherit QThread at all?
Here is my code that declaring the QtThread:
#pragma once
#include <QtCore>
#include <QDebug>
#define qtout qDebug()
class QtThread : public QThread
class QtThread : public QThread
{
Q_OBJECT
public:
QtThread():QThread(nullptr){}
explicit QtThread(const QString &in_name);
// This copy constructor create a different thread with same name, bad
QtThread(const QtThread &in_thread) : QThread() { m_name = in_thread.m_name;} // have to implement copy constructor otherwise, the code will have error: C2280 compile error
//error: C2280: 'QtThread::QtThread(const QtThread &)': attempting to reference a deleted function
//QtThread(const QtThread &in_thread) = default;
void run();
QString m_name;
};
The cpp file
#include "qtthread.h"
QtThread::QtThread(const QString &in_name)
: QThread()
, m_name(in_name)
{}
void QtThread::run()
{
qtout << "QtThread" << m_name << "start to run";
for(int i = 0; i<1000; i++)
qtout << m_name << ": " << i;
}
Here is the main function
#include <QCoreApplication>
#include "qtthread.h"
#include <vector>
#include <algorithm>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::vector<QtThread> ts;
ts.emplace_back(QtThread("Tx"));
ts.emplace_back(QtThread("T5"));
ts.emplace_back(QtThread("T6"));
std::for_each(ts.begin(), ts.end(), [](QtThread &t){t.start();});
return a.exec();
}
Thanks for your time for reading the long post and helping me :)
[Edit 1]
Removed some experimental code from the main function.
Thanks for hyde and cod_fodder made the comments.
There is another detail thing I am wondering. The compiler requires me to overload the copy constructor for QtThread (otherwise compiler throws error CC2280). But what I am trying to do in the main function is move objects into the container. I know when the move operation failed, objects will be copied. In this case, Q_Object is not supposed to be copied, but what is the reason cause the QtThread object unable to be moved?
Thanks
In the blog woboq.com/blog/qthread-you-were-not-doing-so-wrong.html, it states that when event loop is needed, we could use worker/controller pattern, otherwise inherit QThread is good.

Accessing GUI components through C++ code in VC++

I have created a Windows Form Project in VC++ 2010 Express version. So, in that project I created a Form, which had only 1 button and 1 textbox. The name of this form was Form1.
This button called a function FD written in a .cpp file in the same project. However, while running the code, I need to update the textbox with some text. I want to access the textbox through the .cpp file.
I have tried the following:
I included #include "Form1.h" and then wrote textBox1->Text="XYZ". However, while building it says that it cannot find any member called textBox1.
How do I access the textbox from the .cpp file?
EDIT:
FD.cpp
#include<stdafx.h>
#include "Form1.h"
... //other includes
void abc()
{
//Some code
textBox1->Text="String to be displayed."
//Some code
}
Form1.h
This is simple GUI form, where a button called button1 and a textbox called textBox1 is added.
#include<FD.h>
//code generated by the GUI
void button1_click()
{
abc();
}
// FD.cpp
void abc(Form1^ f)
{
// Assuming that textBox1 is public. If not, make it public or make
// public get property
f->textBox1->Text="String to be displayed."
//Some code
}
// Form1.h
void button1_click()
{
abc(this);
}
Or:
// FD.cpp
void abc(TextBox^ t)
{
t->Text="String to be displayed."
//Some code
}
// Form1.h
void button1_click()
{
abc(textBox1);
}
Another way: make abc method return type String^ and set its return value in Form1 to textBox1. Advantage: abc doesn't know anything about UI level. Yet another way: events http://msdn.microsoft.com/en-us/library/58cwt3zh.aspx
The reason you're getting this error is because you haven't specified whose textBox that is. It is not enough to #include the header file, you need to find a way to communicate with your Form1 object. You can do this in several ways.
Using a global pointer to the instance of your main Form1 that can be accessed from anywhere,
Using a local pointer to the instance of your main Form1 that is passed around and can be called upon,
Providing a friend function that can manipulate the data in the class (not recommended),
I would choose 2.

How can I globally access a QT dialog from any class

I have a QT dialog which I need to have access to from anywhere in the program. Basically what I need to do is something like creating a static instance of it somewhere in my program, something like:
'''Note''': This is just an example of what I am trying to do, not actual code (which is too long to post here)
class Core
{
public:
static DialogType *MyDialog;
};
DialogType *Core::MyDialog = NULL;
// later in main.cpp
int main(int argc, char *argv[])
{
try
{
Core::Init();
QApplication a(argc, argv);
Core::MyDialog = new DialogType();
...
However, despite this would work for any other type, it just doesn't work for classes that are inherited from QDialog. The compiler just return: DialogType does not name a type (and yes I do #include that .h file with declaration of DialogType)
What am I doing wrong? Why QT doesn't allow that? How could I make it possible to access single instance of my dialog from ANY class anywhere in the program?
If you are getting an error that the compiler doesn't know what type you are using then you must either insert a forward declaration, or #include a header file that contains either a forward declaration or a definition.
A forward declaration is sufficient if your member type is a pointer or a reference but if it is any other ADT, an #include becomes required.
In the code you posted, you could have:
Core.h:
class DialogType; // forward declaration.
class Core
{
public:
static DialogType *MyDialog;
};
In your source file, you could then have:
Core.cpp:
#include "Core.h"
#include "DialogType.h"
DialogType *Core::MyDialog = new DialogType();
If you genuinely do need just one single, always available instance of that specific class then you could build it off the Singleton pattern so it either creates a pointer and returns it, or just returns a pointer if it's created. Singletons are often recommended as there's plenty of faults with them, but for something along these lines it's probably easier than setting up a static reference to a QDialog inherited class.

Undefined reference to class constructor

Here's my code:
menuState.hpp
#ifndef MENU_STATE_HPP
#define MENU_STATE_HPP
#include "state.hpp"
#include <SFML/Graphics.hpp>
class MenuState : public State
{
public:
MenuState();
static void create(StateListener* Parent, const std::string name)
{
MenuState* myState = new MenuState();
myState->parent = Parent;
Parent->manageState(name, myState);
}
void enter();
void exit();
void resume();
private:
};
#endif // MENU_STATE_HPP
I'm getting an undefined reference to the constructor when I do MenuState* myState = new MenuState(); and I'm not sure why because MenuState::MenuState() comes before the create function in the class declaration.
EDIT: I'm also getting the same error to all my sfml functions.
Here's the exact build messages: http://pastebin.com/e819FhPj
I do have the sfml libraries linked and the header path set in my compilers search directories.
It is always best to show the exact text of the error, but my educated guess is, you are getting a linker error, not a compiler error. Have you actually implemented the constructor anywhere? I bet you haven't.
I'm not an experience C++ developer but it seems like MenuState constructor is declared but not defined.
Replace MenuState(); with MenuState(){} should fix the error.