I want to get a response from the button also if button is only clicked once. The following code only reacts on "double-click". Why does this behavior occur and how can I change that behavior?
#include <iostream>
#include <gtkmm.h>
#include <gtkmm/window.h>
class ExampleWindow: public Gtk::Window
{
Gtk::Button button;
public:
ExampleWindow(): button("Hallo")
{
add(button);
button.signal_button_press_event().connect( [this]( GdkEventButton* ev)->bool{ std::cout << "Press" << std::endl; return true; });
}
};
int main(int argc, char* argv[])
{
Gtk::Main kit(argc, argv);
ExampleWindow window;
window.show_all_children();
Gtk::Main::run(window);
return 0;
}
Related
I am new in QT 4 C++ .I have QT 4 form with QTabwidget like in th picture below.
enter image description here
I want to disply on console the string "aa" by selecting tab on clicking it.
Here is my newForm.h
#ifndef _NEWFORM_H
#define _NEWFORM_H
#include "qwidget.h"
#include "ui_newForm.h"
class newForm : public QDialog {
Q_OBJECT
public:
newForm();
virtual ~newForm();
private:
Ui::newForm widget;
};
#endif /* _NEWFORM_H */
_________________________________________________________________________________________
Here is my main.cpp
#include <QApplication>
#include "newForm.h"
int main(int argc, char *argv[]) {
// initialize resources, if needed
// Q_INIT_RESOURCE(resfile);
QApplication app(argc, argv);
newForm *a = new newForm();
a->show();
// create and show your widgets here
return app.exec();
}
Here is my newForm.cpp
#include "newForm.h"
#include <iostream>
#include <QDebug>
newForm::newForm() {
connect(widget.tabWidget, SIGNAL(stateChanged()), this, SLOT(onTabChanged(int)));
widget.setupUi(this);
}
newForm::~newForm() {
}
void newForm::onTabChanged(int ){
qDebug()<<"aa"<<"\n";
}
On selecting new tab it is not displaying "aa"?How to qDebug() "aa" on console?
First of all, why are you using Qt 4 in 2022?
Next thing use currentIndexChanged(int) istead of stateChanged().
Did you also noticed that stateChanged() doesnt pass an interger which is needed for onTabChanged(int).
You also connected widget.tabWidget which isn't initilized yet.
This code might work:
newForm.h
#ifndef _NEWFORM_H
#define _NEWFORM_H
#include "qwidget.h"
namespace Ui { class newForm; };
class newForm : public QDialog {
Q_OBJECT
public:
newForm();
~newForm();
private:
Ui::newForm *widget;
};
#endif /* _NEWFORM_H */
newForm.cpp
#include "newForm.h"
#include "ui_newForm.h"
#include <QDebug>
newForm::newForm()
: widget(new Ui::newForm)
{
widget->setupUi(this);
connect(widget->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(onTabChanged(int)));
}
void newForm::onTabChanged(int ){
qDebug() << "aa";
}
newForm::~newForm() {
delete widget;
}
main.cpp
#include <QApplication>
#include "newForm.h"
int main(int argc, char *argv[]) {
// initialize resources, if needed
// Q_INIT_RESOURCE(resfile);
QApplication app(argc, argv);
newForm a;
a.show();
// create and show your widgets here
return app.exec();
}
I'm following this document and I'm using qt to implement this event
#include <QCoreApplication>
#include <QDebug>
#include <libvirt/libvirt.h>
void
domainLifecycleCb(virConnectPtr conn,
virDomainPtr dom,
void * opaque)
{
qDebug() << "test";
}
int main(int argc, char *argv[])
{
virEventRegisterDefaultImpl();
QCoreApplication a(argc, argv);
virConnectPtr conn = virConnectOpen("qemu:///session");
virDomainPtr domain = virDomainLookupByName(conn, "Windows");
qDebug() << virConnectDomainEventRegisterAny(conn,
domain,
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_DOMAIN_EVENT_CALLBACK(domainLifecycleCb),
NULL, NULL);
return a.exec();
}
I tried different methods but the event doesn't work when the domain gets shutdown or started.
By that I mean the callback function should get call when the domain life-cycle changes, And I'm determining that by showing an output in the callback function.
There is a function that needs to be called in a loop to keep the connection alive
#include <QCoreApplication>
#include <QDebug>
#include <libvirt/libvirt.h>
#include <QThread>
void domainLifecycleCb(virConnectPtr conn,
virDomainPtr dom,
void * opaque)
{
qDebug() << "test";
}
int main(int argc, char *argv[])
{
virEventRegisterDefaultImpl();
QCoreApplication a(argc, argv);
virConnectPtr conn = virConnectOpen("qemu:///session");
virDomainPtr domain = virDomainLookupByName(conn, "WindowsECO");
QThread *thread = QThread::create([]{
while (true) {
qDebug() << virEventRunDefaultImpl();
} });
thread->start();
qDebug() << virConnectDomainEventRegisterAny(conn,
domain,
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_DOMAIN_EVENT_CALLBACK(domainLifecycleCb),
NULL, NULL);
return a.exec();
}
In QInputDialog how do I get rid of the icons in the OK and Cancel buttons?
Notice the the icons for cancel and ok. I looked through the properties button couldn't figure out how to remove them.
The strategy of the solution is to first obtain the buttons, but these belong to a QDialogButtonBox, so you must use the findChild() method, then reset the icons, there is only one problem, that the buttons are created when necessary, for example when it is visible or when you change the okButtonText or cancelButtonText. For example in the we can force it by making it visible.
#include <QApplication>
#include <QInputDialog>
#include <QDebug>
#include <QAbstractButton>
#include <QDialogButtonBox>
static int getInt(QWidget *parent,
const QString &title,
const QString &label,
int value=0,
int min=-2147483647,
int max=2147483647,
int step=1,
bool *ok=nullptr,
Qt::WindowFlags flags=Qt::Widget)
{
QInputDialog dialog(parent, flags);
dialog.setWindowTitle(title);
dialog.setLabelText(label);
dialog.setIntRange(min, max);
dialog.setIntValue(value);
dialog.setIntStep(step);
dialog.setVisible(true);
for(QAbstractButton *btn: dialog.findChild<QDialogButtonBox*>()->buttons()){
btn->setIcon(QIcon());
}
int ret = dialog.exec();
if (ok)
*ok = !!ret;
if (ret) {
return dialog.intValue();
} else {
return value;
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
bool ok;
int res = getInt(nullptr, "Factorial Calc", "Factorial of:", 5, 0, 100, 1, &ok);
if(ok)
qDebug()<< res;
return 0;
}
But if you use static methods like QInputDialog::getInt() we will not be able to access the QInputDialog directly, we have to do it a moment after showing the QInputDialog with a QTimer, so there are 2 cases:
A parent is passed to the static method:
#include <QApplication>
#include <QInputDialog>
#include <QDebug>
#include <QAbstractButton>
#include <QDialogButtonBox>
#include <QTimer>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget widget;
bool ok;
QTimer::singleShot(0, [&widget](){
QInputDialog *dialog = widget.findChild<QInputDialog *>();
for(QAbstractButton *btn: dialog->findChild<QDialogButtonBox*>()->buttons()){
btn->setIcon(QIcon());
}
});
int res = QInputDialog::getInt(&widget, "Factorial Calc", "Factorial of:", 5, 0, 100, 1, &ok);
if(ok)
qDebug()<< res;
return 0;
}
A parent is not passed to the static method:
#include <QApplication>
#include <QInputDialog>
#include <QDebug>
#include <QAbstractButton>
#include <QDialogButtonBox>
#include <QTimer>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget widget;
bool ok;
QTimer::singleShot(0, [](){
for(QWidget *widget: QApplication::topLevelWidgets()){
if(QInputDialog *dialog = qobject_cast<QInputDialog*>(widget)){
for(QAbstractButton *btn: dialog->findChild<QDialogButtonBox*>()->buttons()){
btn->setIcon(QIcon());
}
}
}
});
int res = QInputDialog::getInt(nullptr, "Factorial Calc", "Factorial of:", 5, 0, 100, 1, &ok);
if(ok)
qDebug()<< res;
return 0;
}
I'm porting my gtkmm2 to gtkmm3 application, this is what I have so far:
// The main.cxx:
#include "alarmui.hxx"
int main (int argc, char *argv[]) {
Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm." PACKAGE_ID);
alarm_ui win(app);
app->run ();
return 0;
}
Header:
// The alarmui.hxx
#ifndef ALARMUI_HXX_INC
#define ALARMUI_HXX_INC
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gtkmm/application.h>
#include <gtkmm/window.h>
#include <gtkmm/statusicon.h>
#include <iostream>
#include <memory>
#include <functional>
class alarm_ui : public Gtk::Window
{
private:
Glib::RefPtr<Gtk::Application> _refApp;
Glib::RefPtr<Gtk::StatusIcon> m_status_icon;
public:
alarm_ui (Glib::RefPtr<Gtk::Application>&);
virtual ~alarm_ui ();
protected:
virtual bool delete_event (GdkEventAny*);
void status_icon_activate_cb ();
};
#endif
source code:
#include "alarmui.hxx"
alarm_ui::alarm_ui (Glib::RefPtr<Gtk::Application>& refApp) : _refApp(refApp)
{
std::cout << "init" << std::endl;
set_icon_from_file (ICON_PNG_PATH);
m_status_icon = Gtk::StatusIcon::create_from_file (ICON_PNG_PATH);
m_status_icon->signal_activate().connect (std::bind(&alarm_ui::status_icon_activate_cb, this));
show_all ();
}
alarm_ui::~alarm_ui () {
std::cout << "done" << std::endl;
}
bool alarm_ui::delete_event (GdkEventAny* event) {
return false;
}
void alarm_ui::status_icon_activate_cb () {
if (get_visible ()) {
iconify ();
hide ();
} else {
deiconify ();
show();
}
}
I'm trying to show my window with a status icon. Toggle the window visibility, while clicking in the status icon. The code compiles fine but seems that when I execute the binary the constructor and destructor are invoked. If I use something like this:
Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm." PACKAGE_ID);
alarm_ui win(app);
app->run (win);
The windows shows, but...as expected, exits on hide() command...any ideas?
Are hold() and release() my only options?
By default, Gtk::Application::run() returns when all the Application's windows have been closed (hidden). Your window (win) will then be destroyed when it goes out of scope when your main() ends.
Gtk::Application::hold() and release() might indeed be what you need. Or maybe you can just do whatever you need to do after run() returns. I guess it depends on what you want to do and when.
I have an Gtk::EventBox with two events connected: button_press_event and scroll_event.
All the two events work fine, but when I hold down a mouse button, the scroll event is not emitted.
I have implement in my class the two functions bool on_button_press_event (GdkEventButton *e) and bool on_scroll_event (GdkEventScroll *e). This two functions return false to propagate the event further.
Im using gtkmm3.
How can I solve this problem?
An example of code to reproduce the problem:
#include <gtkmm.h>
#include <iostream>
class MyWindow : public Gtk::Window
{
Gtk::EventBox event_box;
Gtk::ScrolledWindow scrolled;
public:
bool on_button_press_event(GdkEventButton *b)
{
std::cout << "button press" << std::endl;
return false;
}
bool on_scroll_event(GdkEventScroll *e)
{
std::cout << "scrollEvent" << std::endl;
return false;
}
MyWindow ()
{
add(scrolled);
scrolled.add(event_box);
set_default_size(640, 480);
show_all();
}
};
int main(int argc, char** argv)
{
Gtk::Main kit(argc, argv);
MyWindow window;
kit.run(window);
return 0;
}
The example code you show has two problems.
First, you say "I have an Gtk::EventBox with two events connected." But in your example you connect to MyWindow's events, and leave the EventBox's events unconnected.
An EventBox allows you to receive events, but you still have to explicitly say which events you want to receive.
This is the corrected code:
#include <gtkmm.h>
#include <iostream>
class MyWindow : public Gtk::Window
{
Gtk::EventBox event_box;
bool event_box_button_press(GdkEventButton *b)
{
std::cout << "button press" << std::endl;
return false;
}
bool event_box_scroll(GdkEventScroll *e)
{
std::cout << "scrollEvent" << std::endl;
return false;
}
public:
MyWindow ()
{
event_box.add_events(Gdk::BUTTON_MOTION_MASK);
event_box.add_events(Gdk::SCROLL_MASK);
event_box.signal_button_press_event().connect(
sigc::mem_fun(*this, &MyWindow::event_box_button_press));
event_box.signal_scroll_event().connect(
sigc::mem_fun(*this, &MyWindow::event_box_scroll));
add(event_box);
set_default_size(640, 480);
show_all();
}
};
int main(int argc, char** argv)
{
Gtk::Main kit(argc, argv);
MyWindow window;
kit.run(window);
return 0;
}
Some notes on this code:
I've omitted the ScrolledWindow, as that is irrelevant to the example. You don't need it to catch scroll events. You can add it back if you actually need a scrolled window for your application.
The code would probably be neater if you derive a custom EventBox with the behavior you need. I didn't do this to stay closer to your original code.
See this documentation for information on connecting signals and the sigc::mem_fun stuff.
It looks like on windows, the scrolledWindow was the right place to watch for scroll events instead of the main window.
Using the following modification, I was able to handle scroll events on windows 7.
#include <gtkmm.h>
#include <iostream>
class MyScrolledWindow : public Gtk::ScrolledWindow
{
public:
bool on_scroll_event(GdkEventScroll *e)
{
std::cout << "scrollEvent" << std::endl;
return false;
}
MyScrolledWindow()
{
}
};
class MyWindow : public Gtk::Window
{
Gtk::EventBox event_box;
MyScrolledWindow scrolled;
public:
bool on_button_press_event(GdkEventButton *b)
{
std::cout << "button press" << std::endl;
return false;
}
MyWindow ()
{
add(scrolled);
scrolled.add(event_box);
set_default_size(640, 480);
show_all();
}
};
int main(int argc, char** argv)
{
Gtk::Main kit(argc, argv);
MyWindow window;
kit.run(window);
return 0;
}
====== Old Answer: ================
I am not able to reproduce your isse. This is the code I used to try to reproduce your issue:
#include <gtkmm.h>
#include <iostream>
class MyEventBox : public Gtk::EventBox
{
bool on_button_press_event(GdkEventButton *b)
{
std::cout << "button press" << std::endl;
return false;
}
bool on_scroll_event(GdkEventScroll *e)
{
std::cout << "scrollEvent" << std::endl;
return false;
}
};
int main(int argc, char** argv)
{
Gtk::Main kit(argc, argv);
Gtk::Window window;
MyEventBox eventBox;
eventBox.show();
window.add(eventBox);
kit.run(window);
return 0;
}
For compiling, I used the folowing command line (using Linux):
g++ main.cpp $(pkg-config --cflags --libs gtkmm-3.0)
If you can reproduce your issue using this minimum example, the problem might be platform specific and a workaround using the window's/event box' Gdk::Window might be necessary.
If you can't reproduce your issue using this code, the issue is caused somewhere else in your code and you'll need to post more information.