i'm currently building a very simple music player with the gtk+ and c++ code but now i am unable to figure out how to open and play the audio file using C++ code.
#include <gtk/gtk.h>
// simple music player to practice gtk and c++//
int main(int argc, char* argv[])
{
gtk_init(&argc,&argv);
GtkWidget *window;
GtkWidget *playButton;
GtkWidget *fileButton;
GtkWidget *frame;
GtkWidget *Dialog;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
frame = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window), frame);
playButton = gtk_button_new_with_label("Play");
gtk_widget_set_size_request(playButton,80,40);
gtk_fixed_put(GTK_FIXED(frame),playButton,40,330);
fileButton = gtk_button_new_with_label("Open");
gtk_widget_set_size_request(fileButton,80,40);
gtk_fixed_put(GTK_FIXED(frame),fileButton,40,260);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
so as you can see i have created the open button to select your files and i know the dialog code;
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new ("OpenFile",parent_window,GTK_FILE_CHOOSER_ACTION_OPEN,GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
{
char *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
open_file (filename);
g_free (filename);
}
gtk_widget_destroy (dialog);
but my problem is i do not know how to place the code, i should more than likely create a function and set a callback to that function when the open buttot is clicked. right? And then the second problem coes no matter how hard i search i can't seem to find how to play the audio file, thanks so much in advance!
If you don't mind using external libraries Allegro makes it incredibly easy to play Audio files in a variety of formats. Here is an example of how to play a .wav audio file.
#include <stdio.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_audio.h>
#include <allegro5/allegro_acodec.h>
int main(int argc, char **argv){
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_SAMPLE *sample=NULL;
if(!al_init()){
fprintf(stderr, "failed to initialize allegro!\n");
return -1;
}
if(!al_install_audio()){
fprintf(stderr, "failed to initialize audio!\n");
return -1;
}
if(!al_init_acodec_addon()){
fprintf(stderr, "failed to initialize audio codecs!\n");
return -1;
}
if (!al_reserve_samples(1)){
fprintf(stderr, "failed to reserve samples!\n");
return -1;
}
sample = al_load_sample( "footstep.wav" );
if (!sample){
printf( "Audio clip sample not loaded!\n" );
return -1;
}
display = al_create_display(640, 480);
if(!display){
fprintf(stderr, "failed to create display!\n");
return -1;
}
/* Loop the sample until the display closes. */
al_play_sample(sample, 1.0, 0.0,1.0,ALLEGRO_PLAYMODE_LOOP,NULL);
al_rest(10.0);
al_destroy_display(display);
al_destroy_sample(sample);
return 0;
}
I know I'm incredibly late, but here's my proposal: Use the Gtk4 MediaStream API with Gtk::MediaFile.
Here's a minimal example:
#include <gtkmm.h>
int main(int argc, char ** argv)
{
auto app = Gtk::Application::create();
Gtk::Window w;
Glib::RefPtr<Gtk::MediaFile> mediafile = Gtk::MediaFile::create_for_filename("example.ogg");
mediafile->play();
return app->make_window_and_run<MyWindow>(argc, argv);
}
Compile with:
g++ example.cpp -o example `pkg-config gtkmm-4.0 --libs --cflags`
Related
I have problem with my small app in Qt framework C++
I have a first window which there's two buttons where you can choose to play music or video. The music button will close the "choose window" and should open "music window" and similarly for video button.
I don't know how to do this... I know a way which I've leant and used but this method I'm going to explain how it doesn't fit to my current issue.
I've created a pointer of that window class in header of choose window and when the music button is clicked, I new the pointer and musicWindow->show(); and hide(); the choose window, this is good but there is a problem:
the new opened music window doesn't have any taskbar icon/thumbnail and when Its minimized there's no way to have that opened again(except wtih alt-tab)
and dont find a way to open it like a complete new window, I just can open all of them at once by using choosWindow.show(); / musicWindow.show(); /... .
I know there must be a way, but I dont even know what topics to search for to get further...
FirstWindow.cpp:
void FirstWindow::on_musicChoose_clicked()
{
//send a signal from here
}
void FirstWindow::on_videoChoose_clicked()
{
//send a signal from here
}
main.cpp:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FirstWindow w;
if(//what condition?)
{
MusicWindow mw;
mw.show();
}
if(//what condition?)
{
VideoWindow vw;
vw.show();
}
return a.exec();
}
I found my answer in Qt Forum:
https://forum.qt.io/topic/68602/child-window-in-taskbar/3
#Radek(Qt Forum): Try passing 0 (zero) as parent when you create them.
FirstWindow.cpp:
void FirstWindow::on_musicChoose_clicked()
{
this->hide();
mw = new MusicWindow(0); // passing nullptr as parent
mw.show();
}
void FirstWindow::on_videoChoose_clicked()
{
this->hide();
vw = new VideoWindow(0); // passing nullptr as parent
vw.show();
}
main.cpp:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FirstDialog w;
w.exec();
return a.exec();
}
I know I am missing something really simple here, but all I am trying to do is display a image from a jpg file on a glade form statically w/o a file chooser, here is my code so far, any help would be great.
#include <gtk/gtk.h>
typedef struct {
GtkWidget *w_dlg_file_choose; // Pointer to file chooser dialog box
GtkWidget *w_img_main; // Pointer to image widget
GtkWidget *image;
} app_widgets;
gchar *file_name = "image1.jpg"; // Name of file to open from dialog box
// image = gtk_image_new_from_file ("splash1.jpg");
int main(int argc, char *argv[]) {
GtkBuilder *builder;
GtkWidget *window;
app_widgets *widgets = g_slice_new(app_widgets);
// gchar *file_name = "file.jpg"; // Name of file to open
gtk_init(&argc, &argv);
// image = gtk_image_new_from_file ("splash1.jpg");
builder = gtk_builder_new_from_file("glade/window_main.glade");
window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
widgets->w_dlg_file_choose = GTK_WIDGET(gtk_builder_get_object(builder, "dlg_file_choose"));
widgets->w_img_main = GTK_WIDGET(gtk_builder_get_object(builder, "img_main"));
gtk_builder_connect_signals(builder, widgets);
//image = gtk_image_new_from_file ("myfile.png");
// gtk_image_set_from_file(GTK_IMAGE(app_wdgts->w_img_main), file_name);
g_object_unref(builder);
gtk_widget_show(window);
gtk_main();
g_slice_free(app_widgets, widgets);
return 0;
}
//////////- GUI Button-Signals-"no dragons here" - ///////////////////////////
/////////////////////////////////////////////////////////////////
// Event hanlders. Must be extern "C"
// File --> Open
void on_info_btn_clicked() {
gtk_main_quit();
}
// called when window is closed
void on_window_main_destroy() {
gtk_main_quit();
}
I am using Ubuntu 20.04 and I have a small GTK 3.0 Form I am trying to get to maximize on first startup. I later want to get this into a Full GLADE project, but first I'm just trying to get this to maximize to full screen.
The commented sections are what I have tried to no avail.
Nothing works and it throws compiler errors, can anyone help me in my endeavor?
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
GtkWidget *window;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Center");
// gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
// gtk_window_fullscreen(GTK_WINDOW(window);
// gtk_window_fullscreen(GtkWindow *window);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_widget_show(window);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
Thank you.
Use gtk_window_maximize(GtkWindow *window):
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
GtkWidget *window;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Center");
gtk_window_maximize(GTK_WINDOW(window));
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_widget_show(window);
//...
}
Note that you can call it before showing the window. Doc:
Asks to maximize window , so that it becomes full-screen. Note that you shouldn’t assume the window is definitely maximized afterward, because other entities (e.g. the user or window manager) could unmaximize it again, and not all window managers support maximization. But normally the window will end up maximized. Just don’t write code that crashes if not.
It’s permitted to call this function before showing a window, in which case the window will be maximized when it appears onscreen initially.
You can track maximization via the “window-state-event” signal on GtkWidget, or by listening to notifications on the “is-maximized” property.
Suggestion: Use gtkmm with C++
Example with gtkmm:
#include <gtkmm.h>
int main(int argc, char *argv[])
{
auto app =
Gtk::Application::create(argc, argv,
"org.gtkmm.maximize.base");
Gtk::Window window;
window.maximize();
return app->run(window);
}
I posted this on the Pi forum but the only answer I received is that I posted it in the wrong place.
Posting on Pi forum
I managed to create a program that will display some buttons and an Image. Now I would like to update the image when a button is clicked. How do I do that?
Here is what I have so far, it all works but missing code to update the displayed image. The 3 second delay before camrea.grab is missing from this code but has been add to the code that I am using.
#include <iostream>
#include <raspicam/raspicam.h>
#include <wiringPi.h>
#include <gtk/gtk.h>
#include <fstream>
#include <vector>
#include <unistd.h>
using namespace std;
void Capture_Image(void){
//camera setup
raspicam::RaspiCam camera; //Camera object
if (!camera.open())
{
cerr << "Could not open the camera" << endl;
//return 1;
}
camera.grab();
std::vector<unsigned char> buf;
buf.resize(camera.getImageTypeSize(raspicam::RASPICAM_FORMAT_RGB));
camera.retrieve(buf.data(), raspicam::RASPICAM_FORMAT_RGB);
std::ofstream outFile("/home/pi/s.jpg", std::ios::binary);
outFile << "P6\n" << camera.getWidth() << " " << camera.getHeight() << " 255\n";
outFile.write((char*)buf.data(), buf.size());
cout << "Image saved to output.ppm" << endl;
}
int main(int argc, char **argv)
{
wiringPiSetup();
gtk_init (&argc, &argv);
//Main Box
GtkWidget *mainBox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
gtk_container_add (GTK_CONTAINER (win), mainBox);
//camera image container
GtkWidget *cameraBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
gtk_container_add (GTK_CONTAINER (mainBox), cameraBox);
GtkWidget *cameraView = gtk_image_new_from_file("/home/pi/s.jpg");
gtk_box_pack_start (GTK_BOX (cameraBox), cameraView, TRUE, TRUE, 0);
//resize image
GdkPixbuf *pixBuf = gtk_image_get_pixbuf(GTK_IMAGE(cameraView));
pixBuf = gdk_pixbuf_scale_simple(pixBuf, 300,200,GDK_INTERP_BILINEAR);
gtk_image_set_from_pixbuf(GTK_IMAGE(cameraView),pixBuf);
//image capture button
GtkWidget *imageCapture = gtk_button_new_with_label ("Image Capture");
g_signal_connect (imageCapture, "clicked", G_CALLBACK (Capture_Image), NULL);
gtk_box_pack_start (GTK_BOX (cameraBox), imageCapture, TRUE, TRUE, 0);
//show the new window
gtk_widget_show_all (win);
//Start the GTK main loop
gtk_main ();
return 0;
}
I did a lot of research and found the solution.
I updated my function like this
void Capture_Image(GtkWidget *widget, gpointer image){
And added this code in my function after the image was saved.
GtkWidget *cameraView = (GtkWidget *) image;
gtk_image_set_from_file(GTK_IMAGE(cameraView),"/home/pi/s.jpg");
//resize image
GdkPixbuf *pixBufUpdate = gtk_image_get_pixbuf(GTK_IMAGE(cameraView));
pixBufUpdate = gdk_pixbuf_scale_simple(pixBufUpdate, 320,240,GDK_INTERP_BILINEAR);
gtk_image_set_from_pixbuf(GTK_IMAGE(cameraView),pixBufUpdate);
When I call with the button I used this
g_signal_connect (imageCapture, "clicked", G_CALLBACK (Capture_Image), cameraView);
Here is my code:
#include <gtk/gtk.h>
G_MODULE_EXPORT void waka(GtkWidget *button, GtkWidget* entry1)
{
printf("%s",gtk_entry_get_text(GTK_ENTRY(entry1)));
}
int main(int argc, char * argv[])
{
GtkWidget *window, *button, *entry;
gtk_init(&argc,&argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
button = gtk_button_new_with_label("hha");
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(waka),entry);
entry = gtk_entry_new();
GtkWidget *vbox;
vbox = gtk_vbox_new(FALSE,2);
gtk_box_pack_start_defaults(GTK_BOX(vbox),button);
gtk_box_pack_start_defaults(GTK_BOX(vbox),entry);
gtk_container_add(GTK_CONTAINER(window),vbox);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
When I launch it, and try to fill in some string in the entry box, and then click the button, it said 'segmentation fault'. What is going on?
Also, the callback only works with one user data argument. How about if I want two or more arguments, what must I do in the callback function, and in the call to g_signal_connect()?
the problem is that you're trying to use pointer to entry before initializing it. I've changed a bit your code to fix this, see if it will work for you:
#include <gtk/gtk.h>
void waka(GtkWidget *button, GtkWidget* entry1)
{
g_print("entry: %s\n", gtk_entry_get_text(GTK_ENTRY(entry1)));
}
int main(int argc, char * argv[])
{
GtkWidget *window, *button, *entry, *vbox;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
button = gtk_button_new_with_label("hha");
entry = gtk_entry_new();
vbox = gtk_vbox_new(FALSE, 2);
gtk_box_pack_start_defaults(GTK_BOX(vbox),button);
gtk_box_pack_start_defaults(GTK_BOX(vbox),entry);
gtk_container_add(GTK_CONTAINER(window),vbox);
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(waka), entry);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
hope this helps, regards