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

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

Related

dcmtk display image Qt example

I would like to be able to display in a Dicom image in a Qt project with the same render as a Dicom Viewer Program could give.
I was able to do it but with a very bad contrast. I heard you need to operate on the pixels but I'm not sure. Do you have a working example ?
EDIT: I add my code in case it helps you, I commented a lot of things because I noticed the result was exactly the same
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#undef UNICODE
#undef _UNICODE
#include <dcmtk/config/osconfig.h>
#include <dcmtk/dcmdata/dctk.h>
#include <dcmtk/dcmimgle/dcmimage.h>
#include <QPixmap>
#include <QLabel>
#include <QImageReader>
using namespace std;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//int sizeX = 600;
// int sizeY = 600;
//initialize random seed
//srand (time(NULL));
//QImage image = QImage( sizeX, sizeY, QImage::Format_RGB32 );
/*for( int l=0; l<sizeX; l++ )
{
for( int c=0; c<sizeY; c++ )
{
///Random color for each pixel
//image.setPixel( l, c, qRgb(rand() % 256, rand() % 256, rand() % 256) );
///Fixed color for each pixel
image.setPixel( l, c, qRgb(100, 150, 200) );
}
}*/
const char *file = "/home/x4rkz/project/Laura/QTImage/IMG00000";
DicomImage *image = new DicomImage(file);
if (image != NULL)
{
if (image->getStatus() == EIS_Normal)
{
Uint8 *pixelData = (Uint8 *)(image->getOutputData(8 )); // bits per sample
// Uint8 is a pointer to internal memory buffer
if (pixelData != NULL)
{
// do something useful with the pixel data
QImage img(pixelData,image->getWidth(), image->getHeight(), QImage::Format_Indexed8 );
/*QColor color;
QImage *img;
void *pDicomDibits;
uchar *px;
// uchar pixel[4];
const int width = (int)(image->getWidth());
const int height = (int)(image->getHeight());
if (image->isMonochrome()){
img = new QImage(width, height, QImage::Format_Indexed8);
img->setColorCount(256);
// define gray palette here
for (int i=0; i<256; i++) {
color.setRgb(i, i, i);
img->setColor(i, color.rgb());
}
image->createWindowsDIB(pDicomDibits, 0, 0, 8, 0, 1);
unsigned char * pd;
pd=(unsigned char *)pDicomDibits;
for (int y=0; y < (long) height; y++)
{
px = img->scanLine(y);
for (int x=0; x < (long) width; x++)
{
px[x] = (unsigned char) (*pd);
pd++;
}
}*/
QGraphicsScene * graphic = new QGraphicsScene( this );
graphic->addPixmap( QPixmap::fromImage( img ) );
ui->graphicsView->setScene(graphic);
/* }else
cout << "Non monochrome image" << endl;*/
}
} else
cerr << "Error: cannot load DICOM image (" << DicomImage::getString(image->getStatus()) << ")" << endl;
}
}
MainWindow::~MainWindow()
{
delete ui;
}
#include "mainwindow.h"
#include <QApplication>
#include <iostream>
#undef UNICODE
#undef _UNICODE
#include <dcmtk/config/osconfig.h>
#include <dcmtk/dcmdata/dctk.h>
#include <dcmtk/dcmimgle/dcmimage.h>
#include <QPixmap>
#include <QLabel>
#include <QImageReader>
using namespace std;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
As you cant see, the result has no constrast.
As you cant see, the result has no constrast.
If the rendered image has such a low contrast, you should try to set an appropriate VOI (Value of Interest) window, e.g. using image->setMinMaxWndow(). See API documentation for details.

Why do sometimes two scripts are being launched at the same time?

Explanations: I'm trying to create a daemon-script that will be watching the Watch folder and if I drop some files there - it should run the script.
Problem: sometimes after I drop the file - nothing happens
Script: the script is working with files in the Watch folder and deletes them after.
Additional question: do I have to delete mc object manually or it will be done automatically?
main.cpp
#include "widget.h"
#include <QFileSystemWatcher>
#include <QApplication>
#include <QDebug>
#include "myclass.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QFileSystemWatcher watcher;
watcher.addPath("/home/user/Documents/Watch/");
MyClass* mc = new MyClass;
QObject::connect(&watcher, SIGNAL(directoryChanged(QString)), mc, SLOT(showModified(QString)));
return app.exec();
}
myclass.h
#ifndef MYCLASS
#define MYCLASS
#include <QWidget>
#include <QDir>
#include <QDebug>
#include <QProcess>
class MyClass : public QWidget
{
Q_OBJECT
public:
MyClass(QWidget* parent=0)
:QWidget(parent){}
~MyClass(){}
public slots:
void showModified(const QString& str)
{
if(QDir("/home/user/Documents/Watch/").entryInfoList(QDir::NoDotAndDotDot|QDir::AllEntries).count() == 0)
{
qDebug()<<"EEEMPTYYYY!!!!!!!!!!!!!!!!!!!\n";
_status = false;
}
Q_UNUSED(str)
if (_status == false)
{
_status = true;
QProcess *proc = new QProcess();
proc->setWorkingDirectory("/home/user/Documents/");
proc->startDetached("/home/user/Documents/script.sh");
proc->waitForFinished();
delete proc;
}
}
private:
bool _status = false;
};
#endif // MYCLASS

Transient scrollbar in Qt

I want to use transient scrollbar (Transient scroll bars appear when the content is scrolled and disappear when they are no longer needed) in Qt application. For this purpose I have inheritanced class QproxyStyle and reimplemented function styleHint. Code placed below.
File ScrollBar.h:
#include <QStyle>
#include <QCommonStyle>
#include <QProxyStyle>
class ScrollBarStyle : public QProxyStyle
{
public:
int styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *hret) const;
};
File ScrollBar.c:
#include "ScrollBar.h"
int ScrollBarStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *widget,QStyleHintReturn *hret) const
{
int ret = 0;
switch (sh) {
case SH_ScrollBar_Transient:
ret = true;
break;
default:
return QProxyStyle::styleHint(sh, opt, widget, hret);
}
return ret;
}
File MainWindow.h:
#include <QMainWindow>
#include <QTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
File MainWindow.cpp:
#include <QTextEdit>
#include "MainWindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *l = new (std::nothrow) QTextEdit(this);
if (l == 0)
return;
setCentralWidget(l);
}
MainWindow::~MainWindow()
{
}
File main.cpp:
#include "ScrollBar.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
ScrollBarStyle *style = new (std::nothrow) ScrollBarStyle;
if(style == 0)
return -1;
style->setBaseStyle(a.style());
w.show();
return a.exec();
}
But I have got a problem: transient scrollbar has been appearing only once (when text doesn't fit in the text area) then it has been disappeared and never come back visible.
So how can I fix this problem?
Thanks!
You have forgotten to set the style to application.
a.setStyle(style);

How to create a window without a title bar but with the close/minimize/maximizie buttons in QML?

I want to create an application without the title bar, but with native close, minimize and maximize buttons. This is the intent of the layout:
The app is built using Go and QML. I was able to remove the title bars by adding:
flags: Qt.FramelessWindowHint | Qt.Window
But this means that I'm having to recreate all kinds of native behaviors, like window moving and resizing. I'm also recreating the close/minimize/fullscreen buttons by hand, but it means I lose all kinds of native OS behaviour like the window snapping in windows or the zoom option on mac.
Is there a better way to do this? Is it possible at least to create the native max-min-close buttons instead of building it by scratch?
Thanks for all
You can use objective-c to setup your window correctly. This might be a little buggy, but I got it working through this (create a separate .mm class):
#include "macwindow.h"
#include <Cocoa.h>
MacWindow::MacWindow(long winid)
{
NSView *nativeView = reinterpret_cast<NSView *>(winid);
NSWindow* nativeWindow = [nativeView window];
[nativeWindow setStyleMask:[nativeWindow styleMask] | NSFullSizeContentViewWindowMask | NSWindowTitleHidden];
[nativeWindow setTitlebarAppearsTransparent:YES];
[nativeWindow setMovableByWindowBackground:YES];
}
In your main.cpp you need to pass the window id like this:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QWindow>
#include "macwindow.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QWindowList windows = QGuiApplication::allWindows();
QWindow* win = windows.first();
MacWindow* mac = new MacWindow(win->winId());
return app.exec();
}
In your .pro file you'll need to add the Cocoa reference:
macx:LIBS += -framework Foundation -framework Cocoa
macx:INCLUDEPATH += /System/Library/Frameworks/Foundation.framework/Versions/C/Headers \
/System/Library/Frameworks/AppKit.framework/Headers \
/System/Library/Frameworks/Cocoa.framework/Headers
Not sure why, but I had to add a TextEdit with the focus attribute to get the window drawn correctly, otherwise it appeared just black (my main.qml):
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
ApplicationWindow {
visible: true
color: "white"
width: 600
height: 400
minimumWidth: width
minimumHeight: height
maximumWidth: width
maximumHeight: height
Rectangle {
anchors.fill: parent
color: "white"
TextEdit {
opacity: 0
focus: true
}
}
}
My solution (based on Eduard's one, adjusted so window is draggable).
(Complete source code https://github.com/teimuraz/qt-macos-without-title)
Create macos.h and macos.mm files (If you create it with qt creator rename macos.cpp to macos.mm)
macos.h
#ifndef MACOS_H
#define MACOS_H
#include <QGuiApplication>
#include <QWindow>
class MacOS {
MacOS(long winid);
public:
static void removeTitlebarFromWindow(long winId = -1);
};
#endif // MACOS_H
macos.mm
#include "macos.h"
#include <Cocoa/Cocoa.h>
#include <QGuiApplication>
#include <QWindow>
void MacOS::removeTitlebarFromWindow(long winId)
{
if(winId == -1) {
QWindowList windows = QGuiApplication::allWindows();
QWindow* win = windows.first();
winId = win->winId();
}
NSView *nativeView = reinterpret_cast<NSView *>(winId);
NSWindow* nativeWindow = [nativeView window];
[nativeWindow setStyleMask:[nativeWindow styleMask] | NSFullSizeContentViewWindowMask | NSWindowTitleHidden];
[nativeWindow setTitlebarAppearsTransparent:YES];
[nativeWindow setMovableByWindowBackground:YES];
}
main.qml
import QtQuick
import QtQuick.Controls
ApplicationWindow {
id: mainWindow
visible: true
width: 640
height: 480
// Make windows draggable, currently whole windows area is draggable, but can be adjusted to make draggable only top area
property int previousX
property int previousY
MouseArea {
anchors {
top: parent.top
bottom: parent.bottom
left: parent.left
right: parent.right
}
onPressed: {
previousX = mouseX
previousY = mouseY
}
onMouseXChanged: {
var dx = mouseX - previousX
mainWindow.setX(mainWindow.x + dx)
}
onMouseYChanged: {
var dy = mouseY - previousY
mainWindow.setY(mainWindow.y + dy)
}
}
}
main.cpp
Just add MacWindow::removeTitlebarFromWindow();
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "macos.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(u"qrc:/qt-macos-without-title/main.qml"_qs);
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
MacOS::removeTitlebarFromWindow();
return app.exec();
}
And finally include cocoa lib in .pro file
yourapp.pro
...
macx:LIBS += -framework Foundation -framework Cocoa
macx:INCLUDEPATH += /System/Library/Frameworks/Foundation.framework/Versions/C/Headers \
/System/Library/Frameworks/AppKit.framework/Headers \
/System/Library/Frameworks/Cocoa.framework/Headers

glfwCreateWindow(..) returns null in Visual Studio

I am using the GLFW and only want to open a empty windows.
I downloaded the GLFW for Windows 32.
Created an empty console project and wrote this code:
#include "main.h"
#pragma comment (lib, "glfw3dll")
#pragma comment (lib, "OpenGL32")
#define GLFW_DLL
#include <glfw3.h>
#include <chrono>
#include <iostream>
using namespace std::chrono;
GLFWwindow* window;
bool running = true;
bool initialise(){
return true;
}
void update(double deltaTime){
}
void render(){
}
int main(int argc, char **argv) {
if (!glfwInit)
return -1;
window = (glfwCreateWindow(800, 600, "Hello World", nullptr, nullptr));
if (window == nullptr){
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!initialise()){
glfwTerminate();
return -1;
}
auto currentTimeStamp = system_clock::now();
auto prevTimeStamp = system_clock::now();
while (running)
{
currentTimeStamp = system_clock::now();
auto elapsed = duration_cast<milliseconds>(currentTimeStamp - prevTimeStamp);
auto seconds = double(elapsed.count()) / 1000.0;
update(seconds);
render();
glfwPollEvents();
prevTimeStamp = currentTimeStamp;
}
glfwTerminate();
return -1;
}
And I think I added the library and the header correctly.
But everytime the programm exits with -1 after the glfwCreateWindow(..) function, because this functions return null.
Can somebody help me?
if (!glfwInit)
return -1;
I'm not sure why glfwInit would be NULL unless something truly terrible happened during DLL load.
Try calling glfwInit() instead:
if( !glfwInit() )
return -1;

Resources