Im trying to use the inter-widget drag-and-drop functionalities in GTK3 with gtkmm. Im using Windows 7 x64 (msys2) and gcc 5.3.0.
When i start dragging, the mouse cursor vanishes and the DnD icon is shown at the upper left corner of the screen. Is this a bug or is there something wrong in my code?
Here you can see a very small test application with Gtk::CheckButton as drag source and drag destination.
#include <iostream>
#include <gtkmm-3.0/gtkmm.h>
struct DragButton : Gtk::CheckButton{
DragButton(){
this->signal_drag_begin().connect([](const Glib::RefPtr<Gdk::DragContext>& ctx){
ctx->set_icon();
});
this->drag_source_set({Gtk::TargetEntry("testdata")});
this->drag_dest_set({Gtk::TargetEntry("testdata")});
this->signal_drag_data_get().connect(
[this](const Glib::RefPtr<Gdk::DragContext>&,Gtk::SelectionData& s,guint,guint ){
std::cout << "sending data." << std::endl;
}
);
this->signal_drag_data_received().connect(
[](const Glib::RefPtr<Gdk::DragContext>& c,int,int,const Gtk::SelectionData&,guint,guint time){
std::cout << "receiving data" << std::endl;
c->drop_finish(true,time);
}
);
}
};
int main(){
auto app = Gtk::Application::create("test");
auto settings = Gtk::Settings::get_default();
settings->set_property<Glib::ustring>("gtk-font-name","Sans 10");
Gtk::Window window;
window.set_default_size(100,50);
Gtk::Box box;
for(int i = 0; i < 3; i++){
box.pack_end(*Gtk::manage(new DragButton));
}
window.add(box);
window.show_all();
app->run(window);
}
This screenshot shows the output:
I noticed the same behaviour here. Even with "official" gnome/gtk applications. For example, let's try to drag&drop widgets in Glade: you will have the same "strange" effect.
I think it's a bug of gtk libraries in Windows, but I can't imagine why this isn't solved yet, considering drag&drop is a very useful and used operation.
I found the problem. I found out here that the adwait-icon-theme that is used as a default was not fully windows-compatible. The cursors .cur format were missing. This commit fixed the problem, I had to install the new version of the theme.
Related
I am creating a (pseudo) real-time plotting application in C++, using gnuplot as my backend for plotting. One of my requirements is that the plot must be inside an existing window, instead of having a separate plot window (which gnuplot defaults to).
Gnuplot has an option to specify the (Qt) widget ID which seems like this would fit my use case:
set terminal qt widget <id>
I tried passing the value inside my QtWidget::effectiveWinId() to no avail.
Update: Tried using the internal value of the window id QtWidget::winId() with no luck as well.
The problem is that I cannot find any documentation on what <id> is supposed to be. Is this what the developers of gnuplot intended?
Here's an example of my code:
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtNetwork/QLocalSocket>
int main()
{
QApplication app(argc, argv);
QWidget win(nullptr, Qt::Window);
QWidget *window = win.window();
win.show();
std::cout << "effective win id: " << window->effectiveWinId() << "\n";
std::cout << "effective win id: " << win.effectiveWinId() << "\n";
return app.exec();
}
In gnuplot:
gnuplot> set term qt widget <value from effectiveWinId>
gnuplot> plot x
Could not connect to existing qt widget. Starting a new one.
I'm following this tutorial in the official PCL documentation for the class PCLVisualizer:
http://pointclouds.org/documentation/tutorials/pcl_visualizer.php
and I'm having troubles with the keyboard acquisition: when I select the render window, where the pointcloud is displayed, and try to press "r" or "q", nothing happens and when I try to press the mouse left button, the following text is displayed:
Left mouse button released at position (413, 475)
and the following error is raised (at runtime):
Assertion failed: (px != 0), function operator->, file /usr/local/include/boost/smart_ptr/shared_ptr.hpp, line 687.
Abort trap: 6
I saw that this kind of error happens when you don't initialize the boost::shared_ptr in the declaration of the variable. But in the code listed in the documentation the variable is well defined, so I suppose that the problem concerns the shared_ptr.hpp library, or it isn't?
I've searched over the Internet for a solution, but I haven't found nothing that could solve the issue.
Is there someone that is capable of acquiring keystrokes in the pointcloud's render window by running it on OS X?
If the question is not clear, please let me know.
Thanks a lot for any help or information!
You do not show any code so it's hard to tell what's wrong in your program.
Here is a working example, tested on Ubuntu 14.04 with PCL latest trunk (VTK trunk):
#include <iostream>
#include <pcl/visualization/pcl_visualizer.h>
void keyboardEventOccurred(const pcl::visualization::KeyboardEvent &event, void* viewer_void)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer> *>(viewer_void);
if (event.getKeySym() == "r" && event.keyDown())
std::cout << "'r' was pressed" << std::endl;
if (event.getKeySym() == "h" && event.keyDown())
std::cout << "'h' was pressed" << std::endl;
}
void mouseEventOccurred(const pcl::visualization::MouseEvent &event, void* viewer_void)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer> *>(viewer_void);
if (event.getButton() == pcl::visualization::MouseEvent::LeftButton &&
event.getType() == pcl::visualization::MouseEvent::MouseButtonRelease)
std::cout << "Left mouse button released at position (" << event.getX() << ", " << event.getY() << ")" << std::endl;
}
int main()
{
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer);
viewer->addCoordinateSystem();
viewer->registerKeyboardCallback(keyboardEventOccurred, (void*)&viewer);
viewer->registerMouseCallback(mouseEventOccurred, (void*)&viewer);
viewer->spin();
}
Note that some key-strokes are already used by the PCL visualizer for some actions (press h for more details), but it does not prevent you from using them as well.
This is a fairly simple problem I can't get my head around. It was working before and suddenly now that I'm using std::cout, in the Visual Studio 2013 output window I do not see the output, but I see a bunch of background executions happening. I feel I have messed up something. This is App Game Kit project using C++.
Here's the simple code to output:
#include "template.h"
#include <iostream>
using namespace AGK;
app App;
void app::Begin(void)
{
agk::SetVirtualResolution (1024, 768);
agk::SetClearColor( 151,170,204 );
agk::SetSyncRate(60,0);
agk::SetScissor(0,0,0,0);
std::cout << "Hello"; // SIMPLE PRINT
}
void app::Loop (void)
{
agk::Print( agk::ScreenFPS() );
agk::Sync();
// std::cout << "Hello"; // TRIED HERE TOO (works like update() in Unity3D)
}
This is what my debug window is showing, instead of printing "Hello":
FYI, the program is working perfectly without any errors. Am I looking at the wrong window? where can find my output?
for logging, i write my entries to a file. here is the Contents of my log method in cpp:
void MyFileUtils::log(string msg)
{
ofstream log("logfile.txt", ios_base::app | ios_base::out);
log << msg << endl;
return;
}
i then just call this whenever i want to log something. i have it as a singleton. Then i just look in my media subfolder to see the contents of logfile.txt
Try using this before you return from the method:
log.flush();
log.close();
My goal is to be able to use a joystick inside of Qt (to add a piloting task to an existing Qt app)
Note : Qt 5.4 // SFML 2.2 (running on CentOS7)
In order to do so, I used the tutorial on the sfml website explaining how to insert an sfml window inside of a Qt widget. That tutorial ( http://www.sfml-dev.org/tutorials/1.6/graphics-qt.php ) being too old, I had to change some things in order to update it for sfml 2.2.
However things do not work as intended and while it does compile, it seems to be unable to create the sfml window from the winid and end up crashing
Here is the part of code corresponding to the window creation :
void QSFMLCanvas::showEvent(QShowEvent*)
{
if (!myInitialized)
{
std::cout << "Bla" << std::endl;
// Under X11, we need to flush the commands sent to the server to ensure that
// SFML will get an updated view of the windows
#ifdef Q_WS_X11
XFlush(QX11Info::display());
#endif
std::cout << "Blabla" << std::endl;
// Create the SFML window with the widget handle
sf::WindowHandle HANDLE;
HANDLE = static_cast<sf::WindowHandle>(winId());
std::cout << HANDLE << std::endl;
std::cout << "Blablabla" << std::endl;
sf::RenderWindow::create(HANDLE);
std::cout << "Blablablabla" << std::endl;
// Let the derived class do its specific stuff
OnInit();
// Setup the timer to trigger a refresh at specified framerate
connect(&myTimer, SIGNAL(timeout()), this, SLOT(repaint()));
myTimer.start();
myInitialized = true;
}
}
And here is the output
Bla
Blabla
35651593
Blablabla
...and crash
As you see it seems to have no trouble obtaining the window handle but can't create the sfml renderwindow from it
Note that there is a static_cast for the handle that isn't there in the tutorial. Different questions suggested putting a reinterpret_cast but then it gives me this error
QSFMLCanvas.cpp: In member function ‘virtual void QSFMLCanvas::showEvent(QShowEvent*)’:
QSFMLCanvas.cpp:48:60: erreur: invalid cast from type ‘WId {aka long long unsigned int}’ to type ‘sf::WindowHandle {aka long unsigned int}’
HANDLE = reinterpret_cast<sf::WindowHandle>(winId());
Is there a way to solve this problem ? Or are just SFML & Qt fated to never work together anymore ?
Thank you for your help
My goal is to build a Game Boy emulator. In order to do this, I would like to embed an SDL2 surface into a wxWidgets window.
I found this tutorial: http://code.technoplaza.net/wx-sdl/part1/, but my program crashes as soon as I run it. However I suspect this was intended for SDL1.2. Part of the program is shown below.
It seems that if I call SDL_Init() and also attempt to show a wxFrame (which, in this case, is MainWindow), it shows the window for a second and then the program crashes. I commented all other calls to SDL in my program so far, so it seems the problem lies with calling Show() on a wxFrame and initing SDL2 in the same program.
So the question is: can SDL2 and wxWidgets 3 work together? If not, could you guys suggest to me good alternatives a GUI of a Game Boy emulator? Does wxWidgets have its own graphics frame like Qt does (I'd rather avoid Qt)?
Thanks very much!
#include "MainApp.h"
#include "MainWindow.h"
#include <stdexcept>
namespace GBEmu {
static void initSDL() {
//This and SDL_Quit() are the only calls to the SDL library in my code
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
throw std::runtime_error("Fatal Error: Could not init SDL");
}
}
bool MainApp::OnInit()
{
try {
//If I comment out this line, the MainWindow wxFrame shows up fine.
//If I leave both uncommented, the window shows up quickly and then
//crashes.
initSDL();
//If I comment out this line and leave initSDL() uncommented,
//the program will not crash, but just run forever.
(new MainWindow("GBEmu", {50,50}, {640,480}))->Show();
} catch(std::exception &e) {
wxLogMessage(_("Fatal Error: " + std::string(e.what())));
}
return true;
}
int MainApp::OnExit() {
SDL_Quit();
return wxApp::OnExit();
}
}
wxIMPLEMENT_APP(GBEmu::MainApp);
EDIT: Here is more information on how it crashes: It crashes with a Segfault in what seems to be the pthread_mutex_lock disassembly file. This is the output in the console with stack trace:
Starting /home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx...
The program has unexpectedly finished.
/home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx crashed
Stack trace:
Error: signal 11:
/home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx(_ZN5GBEmu7handlerEi+0x1c)[0x414805]
/lib/x86_64-linux-gnu/libc.so.6(+0x36ff0)[0x7fb88e136ff0]
/lib/x86_64-linux-gnu/libpthread.so.0(pthread_mutex_lock+0x30)[0x7fb88c12ffa0]
/usr/lib/x86_64-linux-gnu/libX11.so.6(XrmQGetResource+0x3c)[0x7fb88d1ca15c]
/usr/lib/x86_64-linux-gnu/libX11.so.6(XGetDefault+0xc2)[0x7fb88d1a7a92]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x94dcf)[0x7fb88af8edcf]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x97110)[0x7fb88af91110]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(cairo_surface_get_font_options+0x87)[0x7fb88af63e07]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x2b61f)[0x7fb88af2561f]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x2ef95)[0x7fb88af28f95]
This is a screenshot of where it seems to fail (line 7):
Update: In my MainWindow class, I attach a menu bar to the window. However, it seems when I comment out the setting of the menu bar, the window will show up fine even with initing of SDL. The menu bar will show up fine if I have initSDL() commented out but not the setting of the menu bar. Here is where I set the menu bar:
MainWindow::MainWindow(const wxString &title, const wxPoint &pos, const wxSize &size)
:wxFrame(nullptr, wxIDs::MainWindow, title, pos, size){
wxMenu *fileMenu = new wxMenu;
fileMenu->Append(wxID_EXIT);
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(fileMenu, "&File");
//commenting this line out will allow the window to showup
//and not crash the program
SetMenuBar(menuBar);
}
You are experiencing an old heisenbug.
The workaround is simple: you have to initialize SDL before wxWidgets (basically, before GTK). To achieve this, you have to change
wxIMPLEMENT_APP(GBEmu::MainApp);
to
wxIMPLEMENT_APP_NO_MAIN(GBEmu::MainApp);
so that wxWidgets doesn't hijack your main().
Then you have to create main() manually. In it, initialize SDL, then call wxEntry():
int main(int argc, char** argv)
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
std::cerr << "Could not initialize SDL.\n";
return 1;
}
return wxEntry(argc, argv);
}
More about the bug:
I have googled around a bit and found that this bug has come up in a few places over the years. There are open reports in many bug trackers that have stack traces very similar to the one you get here (with debug symbols).
The oldest report I could find is from 2005 (!!) from the cairo bug tracker (https://bugs.freedesktop.org/show_bug.cgi?id=4373).
My best guess is that the real hiding place of this bug in either in GTK, cairo, or X. Unfortunately I do not currently have the time to look into it more in depth.