Display the value of an entry - c++

i am using the library Gtkmm with c++ but i have a problem to display the value of an entry. This is my code :
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/main.h>
#include <gtkmm/window.h>
#include <gtkmm/entry.h>
#include <iostream>
int main(int argc, char* argv[]) {
Gtk::Main app(argc, argv);
Gtk::Window fenetre;
Gtk::VBox *boiteV = Gtk::manage(new Gtk::VBox(false, 10));
Gtk::Entry *param = Gtk::manage(new Gtk::Entry());
boiteV->pack_start(*param);
Gtk::Button *bouton = Gtk::manage(new Gtk::Button("Tester !"));
boiteV->pack_start(*bouton);
fenetre.add(*boiteV);
std::string a = param->get_text();
bouton->signal_clicked().connect([&a]() {std::cout << a << std::endl;});
fenetre.show_all();
Gtk::Main::run(fenetre);
return EXIT_SUCCESS;
}
My problem is when i click on the button i have nothing whereas i wrote a value in the entry. Thank you a lot for your help !

The problem is that you take the string a after creation of the button and capture that string (which is empty) in the lambda function. When you press the button, the text is not queried again, but the value of the string a, which never changed, is printed.
You can instead capture the pointer to the button itself (by value!) and call get_text() every time like this:
bouton->signal_clicked().connect(
[param]() {
std::cout << param->get_text() << std::endl;
}
);

Related

How to get global mouse position in Qt6?

I'm trying to get global position of the mouse however the functions mentioned in older topics are either deprecated or not working as intended. I have tried QCursor::pos() as seen below but it didn't work as intended.
#include <QtCore/QCoreApplication>
#include <QCursor>
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
while(1)
{
std::cout << QCursor::pos().x() << " " << QCursor::pos().y() << std::endl;
}
return a.exec();
}
Output: 2147483647 2147483647
It is very simple. QCursor is in the Gui module of Qt see here, so you have to change QCoreApplication to QGuiApplication and then it works (already tested it).

how get destructor called for derived object from Gtk::Window

I want to derive from Gtk::Window and want to create a stand alone window from that object. If the user closes that window, how can I achieve that the destructor of my derived object will be called.
I want to close it in the moment the window is destroyed by user. I tried to do it inside the "on_signal_delete" handler, but that results in segfault.
Currently my code did never call the destructor of the stand alone window!
#include <iostream>
#include <string>
#include <gtkmm.h>
class ExampleWindow : public Gtk::Window
{
protected:
//Child widgets:
Gtk::Box m_VBox;
Gtk::Label m_Label1;
std::string mytext;
public:
ExampleWindow(const std::string& text_):
m_VBox{ Gtk::ORIENTATION_VERTICAL }
,m_Label1{ text_ }
,mytext{ text_ }
{
set_title("Example");
set_border_width(10);
set_default_size(400, 200);
add(m_VBox);
m_VBox.pack_start( m_Label1 );
show_all_children();
}
virtual ~ExampleWindow()
{
// Not called for the stand alone win while closing it. How to achieve that?
std::cout << "Destructor called for " << mytext << std::endl;
}
bool on_delete_event( GdkEventAny* ) override
{
std::cout << "sig on delete called" << mytext << std::endl;
// free( this ); // that results in segfault
return true;
}
};
int main(int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv, "some.base");
ExampleWindow window{ "First Window" };
// Create the same window as free window ( toplevel )
ExampleWindow* win2 = new ExampleWindow("Stand Alone Win");
win2->show(); // How can I desruct this window, if a user closes it?
//Shows the window and returns when it is closed.
return app->run(window);
}
EDIT: As comming up discussion from comments why it is not possible to not use new I provide this more complicated example to show that my real world application has to create the new windows from a signal handler inside gtk. So there is a need to create the objects on demand.
Full example which can create new windows on demand:
#include <iostream>
#include <string>
#include <gtkmm.h>
class ExampleWindow : public Gtk::Window
{
protected:
//Child widgets:
Gtk::Box m_VBox;
Gtk::Button m_button;
std::string mytext;
public:
ExampleWindow(const std::string& text_):
m_VBox{ Gtk::ORIENTATION_VERTICAL }
,m_button{ text_ }
,mytext{ text_ }
{
set_title("Example");
set_border_width(10);
set_default_size(400, 200);
add(m_VBox);
m_VBox.pack_start( m_button );
m_button.signal_clicked().connect(sigc::mem_fun(this,&ExampleWindow::on_clicked));
show_all_children();
}
void on_clicked()
{
ExampleWindow* win2 = new ExampleWindow("Stand Alone Win");
win2->show(); // How can I desruct this window, if a user closes it?
}
virtual ~ExampleWindow()
{
// Not called for the stand alone win while closing it. How to achieve that?
std::cout << "Destructor called for " << mytext << std::endl;
}
bool on_delete_event( GdkEventAny* ) override
{
std::cout << "sighandler on_delete called" << mytext << std::endl;
//delete this; // results in segfault
return false;
}
};
int main(int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv, "some.base");
ExampleWindow window{ "Press to create new win" };
//Shows the window and returns when it is closed.
return app->run(window);
}
The question is still: Where can I hook into the signal handlers to free the dynamically created top level windows.
You dynamically allocate win2 but you never free the memory afterwards.
Call delete on win2 after Gtk::Application::run() returns:
delete win2;
Edit, after a discussion in the comments of this answer
Instead of dynamically allocating your pointer in ExampleWindow::on_clicked(), showing it and then forgetting about it, you should have some sort of a global registry, e.g. an array, of created windows that you can track and destroy when required. Coming up with a design on how to do this is not in scope of the original question so I won't suggest anything more concrete here. You can then even avoid having the dynamic allocation, as it was also suggested below.

gtkmm get size of widget

I simply want to know which size a widget has. I need this info to set a ScrolledWindow to a maximum size if the size of the widget is bigger than the screen.
But all functions I know give a constant value of 1.
#include <iostream>
#include <gtkmm.h>
#include <gtkmm/window.h>
class ExampleWindow: public Gtk::Window
{
Gtk::Button button;
public:
ExampleWindow(): button("Hallo")
{
add(button);
GetSize();
}
void GetSize()
{
std::cout << button.get_width() << " " << button.get_height() << std::endl;
std::cout << button.get_allocated_width() << " " << button.get_allocated_height() << std::endl;
}
};
int main(int argc, char* argv[])
{
Gtk::Main kit(argc, argv);
ExampleWindow window;
window.GetSize();
window.show_all_children();
window.GetSize();
Gtk::Main::run(window);
return 0;
}
This looks a lot like this answer.
Basically it says that before the get_height() and get_width() methods return meaningful values, the widget must be realized. Since you are calling these (through your GetSize() wrapper) inside the window constructor, it (the button inside the window) might not yet be realized, hence the wrong values.
BONUS
According to this ticket:
Realize means to create the GDK resources for a widget. i.e. to
instantiate the widget on the display.
Also, to clarify the meaning of the word realize, see this. The author seems to have done some interesting research on the subject to clarify the documentation.

FLTK button with an image

I am trying to create a button using an image from the list. I want the button to be centered. My code is below. I keep getting the error " request for member ‘W’ in ‘image’, which is of non-class type ‘Fl_GIF_Image(const char*)". I am not sure what I should do. I thought this would give the width of the image. Any ideas?
//
// source.cpp
// labapril20
//
// Created by Kate Godfrey on 4/20/17.
// Copyright (c) 2017 Kate Godfrey. All rights reserved.
//
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_GIF_Image.H>
#include <iostream>
#include <time.h>
#include <vector>
#include <cstdio>
using namespace std;
int main(int argc, char **argv) {
srand(time(NULL)); // set random seed based on current time
vector<string> filenames {"cloudy.gif","fog.gif","lightning.gif","partsunny.gif","rain.gif","sunny.gif"};
string filename = filenames.at(rand() % filenames.size()); // get randome filename
cout << "Image File: " << filename << endl; // for debugging
// Start add code for image on button
Fl_GIF_Image image(const char* filename);
Fl_Window *window = new Fl_Window(image.W(), image.H());
Fl_Button *button = new Fl_Button(0, 0, image.W(), image.H(), filename);
//button->image();
//cout << image.w() << "X" << image.h() << endl; // for debugging
// End code for image on button
window->end();
window->show(argc, argv);
return Fl::run();
}
It is not easy to find someone who also takes Dr.Moore's class haha
try this
Fl_Window* w = new Fl_Window(340, 180);
Fl_GIF_Image* gif = new Fl_GIF_Image("fog.gif");
Fl_Button* Btn01 = new Fl_Button(20,40,gif->w(),gif->h());
Btn01->image(gif);
hope it works!

No output display in console when running a function

I have a problem where I can't seem to get a output to display in a console when doing it through a function.
It works when doing it through Main(), but just blank when doing it through the function.
Below is some of my code:
#include "ConferencePaper.h"
#include "JournalArticle.h"
#include "Reference.h"
#include <QDebug>
#include <QTextStream>
QTextStream cout(stdout);
int main()
{
//QApplication app(argc, argv);
QStringList list1;
list1 << "This is a test";
Reference a("Marius",list1,1,"c"); //Instance of the Reference class created with parameter values
cout << "Title: " << a.getTitle(); //This works fine
a.toString();
return 0;
}
//Reference Function
#include <QString>
#include <QStringList>
#include <QTextStream>
#include "Reference.h"
Reference::Reference(QString ti, QStringList as, int ye, QString id): title(ti), authors(as), year(ye), refID(id){}
QString Reference::toString()
{
return QString("Title: %1\n") .arg(getTitle()); //Does not display anything
}
In your toString() method:
QString Reference::toString() {
return QString("Title: %1\n") .arg(getTitle()); //Does not display anything
}
there is nothing which could cause to print anything on the console. You are simply returning the string as a result of that method.
To display something, you need to output the string which is returned from the method, e.g. in your main() function like
cout << a.toString().toUtf8().constData();
or
cout << a.toString().toLocal8Bit().constData();
Note that you need to convert your QString to a data type for which a << operator is available for ostream. See also How to convert QString to std::string?
As mentioned above several times, X.toString(); would just return QString to a caller, then depending on what you're trying to achieve you may:
print it to console using cout << ...
print it to Application Output pane in your Qt Creator using qDebug() << ...
(see QDebug Class reference for details, it's pretty common debugging technique)