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

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.

Related

TSubclassOf<> isn't storing the class type

I'm trying to create a laser beam actor that spawns when the player presses the "Fire" action mapping. I can't get TSubclassOf<> to work so that I can spawn the actor that creates the laser. I can declare the variable and compile the project, but I can't seem to use the template anywhere else in the project because the variable isn't initialized??? I'll include my code to help explain what's happening.
Here is my LaserTagCharacter.h file. I've declared the LaserClass variable and I can compile this code with no problems.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "LaserTagCharacter.generated.h"
UCLASS()
class LASERTAG_API ALaserTagCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values
ALaserTagCharacter();
UPROPERTY()
TSubclassOf<class ALaserTagLaser> LaserClass;
protected:
// Called when player fires a laser beam
void OnFire();
};
Moving over to the LaserTagCharacter.cpp file, I've included some debug code and my main objective with creating the template class. I created the template class to use it in a SpawnActor function that will spawn an instance of LaserTagLaser.
#include "LaserTagCharacter.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "LaserTagLaser.h"
#include "Engine/World.h"
// Sets default values
ALaserTagCharacter::ALaserTagCharacter()
{
}
// Called when player uses fire action binding
void ALaserTagCharacter::OnFire()
{
UWorld* World = GetWorld();
FVector SpawnLocation = GetActorLocation();
FRotator SpawnRotation = GetControlRotation();
if (LaserClass)
{
UE_LOG(LogTemp, Warning, TEXT("Yes"))
}
else
{
UE_LOG(LogTemp, Warning, TEXT("No"))
}
World->SpawnActor<ALaserTagLaser>(LaserClass, SpawnLocation, SpawnRotation);
}
The 2 messages I get from the output log when I compile, play, and press the "Fire" action mapping are:
LogTemp: Warning: No
and...
LogSpawn: Warning: SpawnActor failed because no class was specified
If you have any insight on how I can fix this and get TSubclassOf<> to work properly, that would be awesome!
Your code seems ok, but you should add in the header file a specifier inside UPROPERTY, and maybe a Category just give it a title
UPROPERTY(EditDefaultsOnly, Category = "Setup")
TSubclassOf<class ALaserTagLaser> LaserClass;
above the TSubclassOf so that UPROPERTY will be editable in the blueprint editor inside unreal as a drop-menu. Then you must a create a new blueprint based on the ALaserTagLaser. After that, open the drop-menu and you will see only classes and childs of classes of the ALaserTagLaser. Select the blueprint you created, click the compile button inside the blueprintEditor, and then it should be working...

Gtkmm 3/C++, closing the program with a button instead of the window "X"

everybody.
I am working on a gtkmm app and need some help getting a "Close" button to work. As suggested by the gtkmm documentation, I derived a class for the main window object, created some members, and left the main() function mostly for reading the glade UI file, instantiating the form and starting the main loop.
There are 3 files, named conveniently for explanation: Declarations.h, Declarations.cpp, Program.cpp
In "Declarations.h" I have the class inherited from the Gtk Window:
#include <gtkmm.h>
class MainWindowClass : public Gtk::ApplicationWindow
{
protected:
Gtk::Button *button_close;
// other buttons here
protected:
void on_button_close_clicked();
// other callback functions here
public:
MainWindowClass(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &refGlade); // Constructor
// Destructor, other public members
};
In "Declarations.cpp" I have the implementations:
#include "Declarations.h"
using namespace Gtk;
// Implementing the constructor
MainWindowClass::MainWindowClass(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &refGlade) :
Gtk::Window(cobject), builder(refGlade)
{
builder->get_widget("button_close", button_close);
// Getting other widgets from the glade file
button_close->signal_clicked().connect(sigc::mem_fun(*this, &MainWindowClass::on_button_close_clicked));
// Connecting other callback functions here
}
// Implementing the callback for the "Close" button, ** PROBLEM IS HERE **
void MainWindowClass::on_button_close_clicked()
{
//gtk_main_quit(); Apparently GTK+/C only, compiler doesn't complain but causes a segfault when clicking the button
//Gtk::Application::quit(); Won't compile
}
The Program.cpp reads the UI from a file and starts the main program loop:
#include <gtkmm.h>
#include "Declarations.h"
int main(int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv, "Damn this close button");
Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_file("Program_UI.glade");
MainWindowClass our_main_window;
return app->run(our_main_window);
}
I am omitting some non-relevant code (of other objects and callbacks) because they work, it is the close procedure that is causing me trouble, though closing the app with "X" works.
I have also thought about trying to call a quit() or destroy() function (if they exist) of "app", but then the callback function doesn't know "app" exists.
What do you guys suggest?
Thanks a lot.
** Edit: fixed this using FormMain::hide(), which is inherited from GtkWindow.
I thought the static procedure Gtk::Main::hide() would do it, but the compiler says that hide() is not a member of Gtk::Main...
Well, moving forward one step at a time.
Used FormMain::hide() (inherited from GtkWindow). The static procedure Gtk::Main::hide() was not being recognized by the compiler.

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();
}

send reference qplaintextedit to C++ constructor class

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");

Run function when push button is clicked

I am using the Qt add in for visual studio. Now I made a simple push button using Qt designer, and I want to use that push button so that it runs a function with a certain inputparameter when it is pressed, and then displays the result that is printed by the function.
The function that I want to run uses the eigen library so requires #include <Eigen/Dense> and should be called as follows:
void coef(Eigen::Matrix<long double, Dynamic, Dynamic> vector, Eigen::Matrix<long double, Dynamic, Dynamic> Matrix)
After I made the push button in Qt designer it automatically already added some code to my header file.
Now I adjusted this header file to the following:
#ifndef QTDEMO_H
#define QTDEMO_H
#include <QtWidgets/QMainWindow>
#include "ui_qtdemo.h"
class qtdemo : public QMainWindow
{
Q_OBJECT
public:
qtdemo(QWidget *parent = 0);
~qtdemo();
private:
Ui::qtdemoClass ui;
// begin new code
public slots:
void on_btnHello_clicked() {
ui.btnHello->coef(v, A); // v and A are defined in main.cpp, so not in this header file
}
// end new code
};
#endif // QTDEMO_H
I know this would of course not work because
the Eigen libary is unknown to this header,
v and A are unknown to this header
3) the function coef() is unknown to this header file.
However, I am unexperienced with using header files, so I don't know what to do to make it work. Could anyone please help? Thanks in advance.
You would need to do the following:
1) #include <Eigen/Dense> in this file.
2) ui.btnHello->coef(v, A); -> coef(v, A);
3) Move v and A as const member variables into this class or make them static here. Although, it would be better to move the implementation into your qtdemo.cpp source file and only leave the declaration in the header.