FLTK button with an image - c++

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!

Related

Incomplete Type is not Allowed QApplication

I am learning C++ with Qt. I have installed Qt 5.15 and am using VS2019. I have the below code (as per an example in a textbook I am working through):
#include <QtGui>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QTextStream cout(stdout);
//declarations of variables
int answer = 0;
do{
//local variables
int factArg = 0;
int fact(1);
factArg = QInputDialog::getInt(0, "Factorial Calculator", "Factorial of:", 1);
cout << "User entered: " << factArg << endl;
int i = 2;
while (i <= factArg) {
fact = fact * i;
++i;
}
QString response = QString("The factorial of %1 is %2.\n%3").arg(factArg).arg(fact).arg("Do you want to compute another factorial?");
answer = QMessageBox::question(0, "Play again?", response, QMessageBox::Yes | QMessageBox::No);
} while (answer == QMessageBox::Yes);
return EXIT_SUCCESS;
}
However, I am recieving the below error when creating an instance of QApplication as app:
Incomplete Type is not Allowed
I am also recieving the below error for the QInputDialog and QMessageBox classes:
name followed by '::' must be a class or namespace name
I am not sure why this is happening - presumably something with a namespace, but I am not sure what scope to provide. I have searched the web but to no avail.
UPDATE
Adding the below header references give cannot open source file error for each.
#include <QApplication>
#include <QInputDialog>
#include <QMessageBox>
I have also added suggestions from the comments to my code, now below:
#include <QtGui>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QTextStream cout(stdout);
//declarations of variables
int answer = 0;
do{
//local variables
int factArg = 0;
int fact(1);
factArg = QInputDialog::getInt(0, "Factorial Calculator", "Factorial of:", 1);
cout << "User entered: " << factArg << endl;
int i = 2;
while (i <= factArg) {
fact = fact * i;
++i;
}
QString response = QString("The factorial of %1 is %2.\n%3").arg(factArg).arg(fact).arg("Do you want to compute another factorial?");
answer = QMessageBox::question(0, "Play again?", response, QMessageBox::Yes | QMessageBox::No);
} while (answer == QMessageBox::Yes);
return EXIT_SUCCESS;
}
But I am still recieving the same errors.
You have to include some qt headers in the app... that is the meaning of the message
you just need to add this to your code
#include <QApplication>
#include <QInputDialog>
#include <QMessageBox>
The correct headers to include are the following:
#include <QtWidgets/QApplication>
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QMessageBox>
Once declaring these, the compiler accepts the code.
I'm going to cut and paste a working program for you.
Qt seems to have a bunch of forward definitions. I can tell I'm missing the right include file if I try to get the IDE to actually help me select a method call. In short, you pretty much have to #include every widget type or other class you're going to use. I haven't run into any shortcuts.
#include <QApplication>
#include "MainWindow.h"
using namespace std;
/**
* Main entry point.
*/
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return app.exec();
}

Qt on Mac: app.exec() blocks terminal input, how to rewrite this minimal example?

I have been reading a lot about this, but I don't fully get how to go about it (e.g. see How to avoid Qt app.exec() blocking main thread).
The following code is a very naievely written minimal example of what I'm trying to achieve. For the sake of this example: there is a terminal in which you put exam grades for the same subject for one student. Concretely: how a student did for his/her English course over the whole year. Every time you put in the grade of a student, a Qt chart updates and shows the progression.
This is the code I wrote:
#include <iostream>
#include <vector>
#include <QApplication>
#include <QMainWindow>
#include <QChartView>
#include <QLineSeries>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
std::vector<int> examScores;
int totalExams = 5;
QtCharts::QLineSeries *series = new QtCharts::QLineSeries();
QtCharts::QChart *chart = new QtCharts::QChart();
chart->legend()->hide();
chart->createDefaultAxes();
QtCharts::QChartView *chartView = new QtCharts::QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(400, 300);
for (int i = 1; i <= totalExams; i++)
{
std::cout << "Enter score of exam " << i << " ";
std::string userInput;
getline(std::cin, userInput);
int score = std::stoi(userInput);
examScores.push_back(score);
series->append(i, score);
chart->addSeries(series);
window.show();
app.exec();
chart->removeSeries(series);
}
return 0;
}
Now, there are many issues here from a software engineering perspective (e.g. not sanitizing input, and so on), but what I can't wrap my head around is how to rewrite app.exec();. I know it shouldn't be there, since it's blocking, and I know Qt isn't meant to be written this way.
So I'm wondering: how would you rewrite this example in order to make app.exec(); non-blocking and allow the program to receive user input on the terminal at all times?
This is how I put it into its own thread while still being able to handle CLI input. A lot of things are still wrong with this code from a code review perspective, but the basic functionality (putting it into a different thread) works.
#include <iostream>
#include <vector>
#include <thread>
#include <QApplication>
#include <QMainWindow>
#include <QChartView>
#include <QLineSeries>
std::vector<int> examScores;
void pollForUserInput(QtCharts::QLineSeries *series, int totalExams)
{
for (int i = 1; i <= totalExams; i++)
{
std::cout << "\nEnter score of exam " << i << " " << std::endl;
std::string userInput;
getline(std::cin, userInput);
int score = std::stoi(userInput);
examScores.push_back(score);
series->append(i, score);
}
std::cout << "done" << std::endl;
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QtCharts::QLineSeries *series = new QtCharts::QLineSeries();
int totalExams = 5;
std::thread t1(pollForUserInput, series, totalExams);
QtCharts::QChart *chart = new QtCharts::QChart();
chart->legend()->hide();
chart->addSeries(series);
chart->createDefaultAxes();
chart->axisX()->setRange(1, totalExams); // see https://stackoverflow.com/questions/38804179/how-to-repaint-a-qchart
chart->axisY()->setRange(1, 10); // see https://stackoverflow.com/questions/38804179/how-to-repaint-a-qchart
QtCharts::QChartView *chartView = new QtCharts::QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(400, 300);
window.show();
return app.exec();
}

Display the value of an entry

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

QPixmap does not open some image

It opens one JPEG image but not the other JPEG. The directories and files exist on my system. For ease of recreation the images used in the below code are console test and f2.
#include "mainwindow.h"
#include <QApplication>
#include <QPixmap>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
QPixmap *pixmap = new QPixmap;
pixmap->load("C:/Programs/console test.jpg");
if(pixmap->isNull())
cout << "darn" << endl;
else
cout << "not null" << endl;
pixmap->load("C:/Programs/f2.jpg");
if(pixmap->isNull())
cout << "darn" << endl;
else
cout << "not null" << endl;
return a.exec();
}
The above code prints
darn
not null
If relevant, the application is a QWidget application.
console test.jpg is actually a PNG file. – Oktalist
Oktalist answered the question. I naively used and changed the extension from png to jpg expecting file conversion. After undoing the change with the same method, the image successfully opens.
ifstream src("console print.jpg", ios::binary);
ofstream dest("console print.png", ios::binary);
dest << src.rdbuf();
dest.flush();
And now console print has the correct file extension. And it opens. There are a billion other ways you could do this, but this one was easy.
-Sanfer

Trying to detect monitor

I'm trying to get the monitor in order to check if is off or not.
Before checking with GetDevicePowerState, I'm trying to retrieve monitor in this way:
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <winuser.h>
using namespace std;
int main(int argc, char *argv[])
{
POINT* p = new POINT;
p->x=0;
p->y=0;
HMONITOR* monitor = MonitorFromPoint(p,DWORD.MONITOR_DEFAULTTOPRIMARY);
system("PAUSE");
return EXIT_SUCCESS;
}
But it continually gives me:
main.cpp `MonitorFromPoint' undeclared (first use this function)
Where have I gone wrong?
Your code has a number of problems, but none of them should cause the error message you're seeing. Here's code with some corrections, and a little more added to show at least some kind of result from the test:
#include <iostream>
#include <windows.h>
int main(int argc, char *argv[])
{
POINT p{ 0, 0 };
HMONITOR monitor = MonitorFromPoint(p, MONITOR_DEFAULTTONULL);
if (monitor == NULL)
std::cout << "No monitor found for point (0, 0)\n";
else {
MONITORINFOEX info;
info.cbSize = sizeof(info);
GetMonitorInfo(monitor, &info);
std::cout << "Monitor: " << info.szDevice << "\n";
}
}
I've tested this with both VC++ 2013 and MinGW 4.8.1, and in both cases it's compiled and run without any problems, producing:
Monitor: \\.\DISPLAY1
...as its output in both cases.