PCL viewer inside QtCreator widget with VTK and QVTKOpenGLStereoWidget - qt-creator

I need to make a graphical window with a Qt widget that allows to represent inside it a point cloud that I have previously loaded using the PLC library.
Here's what I have so far that doesn't work (I based it on tutorials and this answer).
I'm using:
Ubuntu 20.04
Qt Creator 5.15
VTK 9.1
PCL 1.12
The reason I am using QVTKOpenGLStereoWidget is that as far as I read both QVTKOpenGLWidget and QVTKWidget are no longer available or will be discontinued in future releases.
Test.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++14
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
MainWindow.cpp
HEADERS += \
MainWindow.h
FORMS += \
MainWindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
# INCLUIR LAS LIREARÍAS PARA EL PRROGRAMA
VTK_VERSION = 9.1
PCL_VERSION = 1.12
CONFIG += link_pkgconfig
# LIBREARÍA DE ARCHIVOS DE EIGEN3
PKGCONFIG += eigen3
# LIBRERÍA DE ARCHIIVOS DE BOOST
INCLUDEPATH += /usr/include/boost
# LIBREARÍA DE REPRESENTACIÓN GRÁFICA VTK
INCLUDEPATH += /usr/local/include/vtk-$${VTK_VERSION}
LIBS += -L/usr/local/lib \
-lvtkCommonColor-$${VTK_VERSION} \
-lvtkCommonCore-$${VTK_VERSION} \
-lvtkFiltersSources-$${VTK_VERSION} \
-lvtkInteractionStyle-$${VTK_VERSION} \
-lvtkRenderingContextOpenGL2-$${VTK_VERSION} \
-lvtkRenderingCore-$${VTK_VERSION} \
-lvtkRenderingFreeType-$${VTK_VERSION} \
-lvtkRenderingGL2PSOpenGL2-$${VTK_VERSION} \
-lvtkRenderingOpenGL2-$${VTK_VERSION} \
-lvtkCommonExecutionModel-$${VTK_VERSION} \
-lvtkRenderingFreeType-$${VTK_VERSION} \
-lvtkInteractionStyle-$${VTK_VERSION} \
-lvtkRenderingOpenGL2-$${VTK_VERSION} \
-lvtkRenderingLOD-$${VTK_VERSION} \
-lvtkCommonDataModel-$${VTK_VERSION} \
-lvtkCommonMath-$${VTK_VERSION} \
-lvtkViewsQt-$${VTK_VERSION} \
#-lvtkGUISupportQtOpenGL-$${VTK_VERSION} \
-lvtkGUISupportQt-$${VTK_VERSION}
# LIBRERÍAS PARA EL TRBAJO CON NUBES DE PUNTOS.
INCLUDEPATH += /usr/local/include/pcl-$${PCL_VERSION}
LIBS += -L/usr/local/lib \
-lpcl_common -lpcl_features -lpcl_filters -lpcl_io_ply \
-lpcl_io -lpcl_kdtree -lpcl_keypoints -lpcl_ml \
-lpcl_octree -lpcl_outofcore -lpcl_people -lpcl_recognition \
-lpcl_registration -lpcl_search -lpcl_segmentation -lpcl_stereo \
-lpcl_surface -lpcl_tracking -lpcl_visualization -lpcl_sample_consensus
MainWindow.ui
It only has one widget that has a promote a QVTKOpenGLSTereoWidget
MainWindow.h
I did the initialization of the VTK library, the inclusion of the different library headers and created the PCL viewer and the VTK renderer based on OpenGL.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "pcl/visualization/cloud_viewer.h"
#include <pcl/visualization/pcl_visualizer.h>
#include "pcl/io/pcd_io.h"
#include "pcl/io/ply_io.h"
#include "pcl/io/obj_io.h"
#include "pcl/common/io.h"
#include "vtkCylinder.h"
#include "vtkCylinderSource.h"
#include "vtkRenderWindow.h"
#include <QVTKOpenGLWidget.h>
#include <QVTKOpenGLStereoWidget.h>
#include <QVTKOpenGLWindow.h>
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
using namespace pcl::visualization;
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
pcl::visualization::PCLVisualizer::Ptr viewer;
vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow;
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
MainWindow.cpp
Finally in the constructor of the MainWindow class I simply loaded the file (in this case it was a PLY) and then I tried to make the graphical representation in the widget
#include "MainWindow.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB>);
// Cargar el objeto en dicha nube de putnos en el formato que se desee.
pcl::io::loadPLYFile("/home/alejandro/Documentos/alejandro.ply",*cloud);
viewer->addPointCloud(cloud);
auto renderer = vtkSmartPointer<vtkRenderer>::New();
renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
//renderWindow->AddRenderer(renderer); THIS MAKES AN ERROR!!
viewer.reset(new PCLVisualizer(renderer, renderWindow, "viewer", false));
ui->widget->setRenderWindow(viewer->getRenderWindow());
ui->widget->update();
}
MainWindow::~MainWindow()
{
delete ui;
}
Main.cpp
I have not changed anything, it is default
#include "MainWindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
ERROR.
The main error I have is: /usr/local/include/vtk-9.1/vtkSmartPointer.h:225: error: incomplete type ‘vtkGenericOpenGLRenderWindow’ used in nested name specifier
In file included from /usr/local/include/pcl-1.12/pcl/visualization/point_cloud_geometry_handlers.h:49,
from /usr/local/include/pcl-1.12/pcl/visualization/common/actor_map.h:40,
from /usr/local/include/pcl-1.12/pcl/visualization/pcl_visualizer.h:48,
from /usr/local/include/pcl-1.12/pcl/visualization/cloud_viewer.h:39,
from ../04_pcl_viewer_V3/MainWindow.h:6,
from ../04_pcl_viewer_V3/MainWindow.cpp:1:
/usr/local/include/vtk-9.1/vtkSmartPointer.h: In instantiation of ‘static vtkSmartPointer vtkSmartPointer::New() [with T = vtkGenericOpenGLRenderWindow]’:
../04_pcl_viewer_V3/MainWindow.cpp:16:67: required from here
/usr/local/include/vtk-9.1/vtkSmartPointer.h:225:69: error: incomplete type ‘vtkGenericOpenGLRenderWindow’ used in nested name specifier
225 | static vtkSmartPointer New() { return vtkSmartPointer(T::New(), NoReference()); }
| ~~~~~~^~

I was finally able to find the solution to the problem so I am sharing it as an answer in case it could be useful for someone else.
pclTest_V0.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++14
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
MainWindow.cpp
HEADERS += \
MainWindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
# Incluir la librería y la ruta de VTK
VTK_VERSION = 9.1
INCLUDEPATH += /usr/local/include/vtk-$${VTK_VERSION}
LIBS += -L/usr/local/lib \
-lvtkCommonColor-$${VTK_VERSION} \
-lvtkCommonExecutionModel-$${VTK_VERSION} \
-lvtkCommonCore-$${VTK_VERSION} \
-lvtkCommonDataModel-$${VTK_VERSION} \ # Para PCL
-lvtkCommonMath-$${VTK_VERSION} \ # Para PCL
-lvtkFiltersCore-$${VTK_VERSION} \
-lvtkFiltersSources-$${VTK_VERSION} \
-lvtkInfovisCore-$${VTK_VERSION} \
-lvtkInteractionStyle-$${VTK_VERSION} \
-lvtkRenderingContextOpenGL2-$${VTK_VERSION} \
-lvtkRenderingCore-$${VTK_VERSION} \
-lvtkRenderingFreeType-$${VTK_VERSION} \
-lvtkRenderingGL2PSOpenGL2-$${VTK_VERSION} \
-lvtkRenderingOpenGL2-$${VTK_VERSION} \
-lvtkViewsQt-$${VTK_VERSION} \
-lvtkGUISupportQt-$${VTK_VERSION} \
-lvtkRenderingQt-$${VTK_VERSION}
# Incluir el directorio de boost.
INCLUDEPATH += /usr/include/boost
# Incluir el direcotrio de eigen3.
INCLUDEPATH += /usr/include/eigen3
# Incluir las librerías y la ruta de PCL.
PCL_VERSION = 1.12
INCLUDEPATH += /usr/local/include/pcl-$${PCL_VERSION}
LIBS += -L/usr/local/lib \
-lpcl_common -lpcl_io -lpcl_visualization
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "pcl/common/common_headers.h"
#include "pcl/features/normal_3d.h"
#include "pcl/io/obj_io.h"
#include "pcl/io/ply_io.h"
#include "pcl/visualization/pcl_visualizer.h"
#include "pcl/console/parse.h"
#include "QVTKOpenGLNativeWidget.h"
#include "vtkCamera.h"
#include "vtkCubeSource.h"
#include "vtkDataObjectToTable.h"
#include "vtkElevationFilter.h"
#include "vtkGenericOpenGLRenderWindow.h"
#include "vtkNamedColors.h"
#include "vtkNew.h"
#include "vtkPolyDataMapper.h"
#include "vtkQtTableView.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkSphereSource.h"
#include "vtkVersion.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
pcl::visualization::PCLVisualizer::Ptr viewer;
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "MainWindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
vtkNew<vtkGenericOpenGLRenderWindow> renderWindow;
vtkNew<vtkRenderer> renderer;
renderWindow->AddRenderer(renderer);
// Crear una nube de puntos con los datos almacenados en un archivo
// determinado.
std::string name = "filename.ply";
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::io::loadPLYFile(name,*cloud);
// Generar el visor de la nube de puntos para realizar la visualización.
//viewer.reset(new pcl::visualization::PCLVisualizer("viewer",false));
viewer.reset(new pcl::visualization::PCLVisualizer(renderer, renderWindow,
"viewer",false));
viewer->addPointCloud(cloud);
//ui->Viewer_widget->renderWindow()->AddRenderer(renderer);
ui->Viewer_widget->setRenderWindow(viewer->getRenderWindow());
ui->Viewer_widget->update();
}
MainWindow::~MainWindow()
{
delete ui;
}
main.cpp
#include "MainWindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
MainWindow.ui
Widget with QVTKOpenGLNativeWidget.h promotion.

Related

ipref3 dll for windows

I try to build ipref3.dll for windows
I found How to compile iperf3 for Windows
Built it but i got only iperf3.exe and libiperf.a
I found, how create dll manual
gcc -s -shared -o iperf3.dll units.o timer.o tcp_window_size.o tcp_info.o net.o iperf_util.o iperf_sctp.o iperf_udp.o iperf_tcp.o iperf_server_api.o iperf_locale.o iperf_client_api.o iperf_error.o iperf_api.o cjson.o -Wl,--enable-auto-import,--export-all-symbols,--subsystem,windows
after i found how need to initialize
HMODULE h = LoadLibrary(TEXT("cygwin1.dll"));
PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT)GetProcAddress(h, "cygwin_dll_init");
init();
Now i can load dll and make initialization but when i start test iperf_run_client application is crashed
Unhandled exception at 0x611537C0 (cygwin1.dll) in iprerf-server.exe:
0xC0000005: Access violation reading location 0x00740000.
How can solve this problem?
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <WinSock2.h>
//#include <unistd.h>
#include <string.h>
//#include <sysexits.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include "iperf_api.h"
#ifdef WIN64
#pragma comment(lib, "iperf3_64.lib")
#else
#pragma comment(lib, "iperf3.lib")
#endif
#pragma comment(lib, "ws2_32.lib")
typedef void *register_frame();
typedef int *hello_f();
typedef int(*PFN_HELLO)();
typedef void(*PFN_CYGWIN_DLL_INIT)();
#pragma pack(push, 1)
int main(int argc, char** argv)
{
WSADATA wsaData;
int wsaErr = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (wsaErr != 0) {
printf("WSAStartup failed with error: %d\n", wsaErr);
return 1;
}
//PFN_HELLO fnHello;
HMODULE /*hLib, */h = LoadLibrary(TEXT("cygwin1.dll"));
PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT)GetProcAddress(h, "cygwin_dll_init");
init();
char* argv0;
char* host;
int port;
struct iperf_test *test;
argv0 = strrchr(argv[0], '/');
if (argv0 != (char*)0)
++argv0;
else
argv0 = argv[0];
if (argc != 3) {
fprintf(stderr, "usage: %s [host] [port]\n", argv0);
exit(EXIT_FAILURE);
}
host = argv[1];
port = atoi(argv[2]);
test = iperf_new_test();
if (test == NULL) {
fprintf(stderr, "%s: failed to create test\n", argv0);
exit(EXIT_FAILURE);
}
iperf_defaults(test);
iperf_set_verbose(test, 1);
iperf_set_test_role(test, 'c');
iperf_set_test_server_hostname(test, host);
iperf_set_test_server_port(test, port);
/* iperf_set_test_reverse( test, 1 ); */
iperf_set_test_omit(test, 3);
iperf_set_test_duration(test, 5);
iperf_set_test_reporter_interval(test, 1);
iperf_set_test_stats_interval(test, 1);
/* iperf_set_test_json_output( test, 1 ); */
if (iperf_run_client(test) < 0) {
fprintf(stderr, "%s: error - %s\n", argv0, iperf_strerror(i_errno));
exit(EXIT_FAILURE);
}
if (iperf_get_test_json_output_string(test)) {
fprintf(iperf_get_test_outfile(test), "%zd bytes of JSON emitted\n",
strlen(iperf_get_test_json_output_string(test)));
}
iperf_free_test(test);
exit(EXIT_SUCCESS);
}
The reason why the shared lib is not built is:
libtool: warning: undefined symbols not allowed in x86_64-unknown-cygwin
shared libraries; building static only
the easy way to bypass it, in a clean build is to use:
$ make libiperf_la_LIBADD="-no-undefined"
The build will include the shared libray and the import library
$ find . -name "*dll*"
./src/.libs/cygiperf-0.dll
./src/.libs/libiperf.dll.a
For what I see to make a build on cygwin is also needed to remove a definition
in src/iperf_config.h after running configure
/* #define HAVE_SETPROCESSAFFINITYMASK 1 */
PS #1: iperf-2.0.5-1 is available as cygwin package
PS #2: your code is Windows-like while Cygwin is a Unix-like system, you can not mix them
I found solution
1) It need to create addition dll: my_crt0.dll
#include <sys/cygwin.h>
#include <stdlib.h>
typedef int (*MainFunc) (int argc, char *argv[], char **env);
void my_crt0 (MainFunc f)
{
cygwin_crt0(f);
}
gcc -c my_crt0.c
gcc -o my_crt0.dll my_crt0.o -s -shared -Wl,--subsystem,windows,--enable-auto-import,--export-all-symbols,--out-implib,my_crt0.lib
2) Modify main code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <WinSock2.h>
#include <string.h>
#include "iperf_api.h"
#pragma comment(lib, "iperf3.lib")
#pragma comment(lib, "ws2_32.lib")
typedef int(*MainFunc) (int argc, char *argv[], char **env);
typedef void(*my_crt0)(MainFunc f);
int main2(int argc, char** argv, char **env)
{
char* argv0;
char* host;
int port;
struct iperf_test *test;
host = (char*)"127.0.0.1";
port = 4000;
test = iperf_new_test();
if (test == NULL) {
exit(EXIT_FAILURE);
}
iperf_defaults(test);
iperf_set_verbose(test, 1);
iperf_set_test_role(test, 'c');
iperf_set_test_server_hostname(test, host);
iperf_set_test_server_port(test, port);
/* iperf_set_test_reverse( test, 1 ); */
iperf_set_test_omit(test, 3);
iperf_set_test_duration(test, 5);
iperf_set_test_reporter_interval(test, 1);
iperf_set_test_stats_interval(test, 1);
/* iperf_set_test_json_output( test, 1 ); */
iperf_strerror(0);
if (iperf_run_client(test) < 0) {
fprintf(stderr, "%s: error - %s\n", argv0, iperf_strerror(i_errno));
exit(EXIT_FAILURE);
}
if (iperf_get_test_json_output_string(test)) {
fprintf(iperf_get_test_outfile(test), "%zd bytes of JSON emitted\n",
strlen(iperf_get_test_json_output_string(test)));
}
iperf_free_test(test);
exit(EXIT_SUCCESS);
return 1;
}
int main(int argc, char** argv)
{
WSADATA wsaData;
int wsaErr = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (wsaErr != 0) {
printf("WSAStartup failed with error: %d\n", wsaErr);
return 1;
}
{
HMODULE /*hLib, */h = LoadLibrary(TEXT("my_crt0.dll"));
my_crt0 init = (my_crt0)GetProcAddress(h, "my_crt0");
init(main2);
}
exit(EXIT_SUCCESS);
}
Now it compiled and worked to VS 2015

Opencv program using qtcreator undefined reference in ubuntu for imread or any string

include "mainwindow.h"
include "ui_mainwindow.h"
include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
cv::Mat inputImage = cv::imread("/home/chaiein/VR/1.jpg");
cv::imshow("Display Image", inputImage);
}
MainWindow::~MainWindow()
{
delete ui;
}
Error
/home/chaiein/VR/linePose/mainwindow.cpp:11: error: undefined reference to `cv::imread(std::__cxx11::basic_string, std::allocator > const&, int)'
My linepose.pro file as the following content
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = linePose
TEMPLATE = app
INCLUDEPATH += /usr/local/include/opencv /opt/ros/kinetic/share/OpenCV-
3.2.0-dev
LIBS += -L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_highgui
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
I have searched in many links but this problem seems to have different solution please help me!!

Link error with Qt5 webkit

I want to make a browser in qt5 using qtwebkit but I found some error when I get download my site. I don't know the reason. I added the webkit library, and call it in mainwindow.h:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtWebKit/QtWebKit>
namespace Ui { class MainWindow; }
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
private:
Ui::MainWindow *ui; };
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
ui->webView->back();
}
void MainWindow::on_pushButton_2_clicked()
{
ui->webView->forward();
}
void MainWindow::on_pushButton_3_clicked()
{
ui->webView->reload();
}
void MainWindow::on_pushButton_4_clicked()
{
ui->webView->load("http://" + ui->lineEdit->text());
}
and this when i called library
#-------------------------------------------------
#
# Project created by QtCreator 2013-10-31T07:39:06
#
#-------------------------------------------------
QT += core gui QT += webkit
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = mozilabrwser TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
I tried to change the name of webkit but I still get this error:
D:\ubunto\QT5\Tools\QtCreator\bin\mozilabrwser\mainwindow.cpp:19: error:
undefined reference to `_imp___ZN8QWebView4backEv'
QT += core gui QT += webkit
is wrong. You seem to be using Qt 5, and in Qt 5 the correct module is webkitwidgets. 2nd issue is format, you seem to have two lines concatenated. So this should work:
QT += core gui
QT += webkitwidgets
Note: If you need to have the program compile with both Qt4 and Qt5, then you need to use conditional, adding webkit for Qt4, webkitwidgets for Qt5. But this is probably not a concern for a hobby project, no point clutteirng the .pro file with that stuff until you actually need it (you will also need some source changes and #ifdef stuff in code if you want to support both, so don't go there unless it is an important requirement).
Same two lines concatenated issue seems to be also in line TARGET = mozilabrwser TEMPLATE = app.

How to programmatically disable scrollbar inertia for my Qt application on a Mac?

In a Qt project, how would I go about disabling the OS X scrollbar inertia for my application? This is so that I can provide custom control over inertia etc.
This does it:
project.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = project
TEMPLATE = app
macx {
LIBS += -framework Foundation
OBJECTIVE_SOURCES += helper.m
}
SOURCES += main.cpp
helper.m
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSString.h>
void disableMomentumScroll(void)
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:#"NO" forKey:#"AppleMomentumScrollSupported"];
[defaults registerDefaults:appDefaults];
}
main.cpp
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#ifndef Q_OS_MAC
void disableMomentumScroll() {}
#else
extern "C" { void disableMomentumScroll(); }
#endif
float rnd(float range) { return (qrand() / static_cast<float>(RAND_MAX)) * range; }
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
disableMomentumScroll();
QGraphicsScene s;
for (int n = 0; n < 30; n++) {
s.addRect(rnd(500), rnd(3000), rnd(200), rnd(1000), QPen(Qt::red), QBrush(Qt::gray));
}
QGraphicsView w(&s);
w.show();
return a.exec();
}

What is the exact equivalent to LD_PRELOAD on OSX?

I am using LD_PRELOAD to hook a library function, and in Linux it works perfectly. But I cannot figure out how to do the equivalent in OSX.
The setup I have on Linux is as follows:
The code is:
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <unistd.h>
#include <ruby.h>
void
rb_raise(unsigned long exc, const char *fmt, ...)
{
static void (*libruby_rb_raise)
(unsigned long exc, const char *fmt, ...) = NULL;
void * handle;
char * error;
if (!libruby_rb_raise) {
handle = dlopen("/path/to/libruby.so",
RTLD_LAZY);
if (!handle) {
fputs(dlerror(), stderr);
exit(1);
}
libruby_rb_raise = dlsym(handle, "rb_raise");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(1);
}
}
// ...code...
return Qnil;
}
Which I then compile with:
gcc -Wall -O2 -fpic -shared -ldl -g -I/path/to/includes/ -o raise_shim.so raise_shim.c
I then execute with:
LD_PRELOAD=./raise_shim.so ruby
All of the above works well on Linux, what is the equivalent for each step to get this working on OSX? I have googled this and have not been able to get it to work with the information provided as the info for some of the steps are missing.
Thanks in advance!
Take a look at DYLD_INSERT_LIBRARIES. That's the variable you're looking for.
See also this answer.

Resources