Qt GraphicsScene on Widget - qwidget

How to add Graphics Scene/Graphics View to Widget?
Code here

This is my Solution:
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QGraphicsView>
#include <QGraphicsTextItem>
#include <QGraphicsScene>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget *window = new QWidget;
window->resize(300, 200);
QVBoxLayout *layout = new QVBoxLayout(window);
QGraphicsScene scene;
QGraphicsView *view = new QGraphicsView(&scene);
QGraphicsTextItem *text = scene.addText("Hello World");
layout->addWidget(view);
window->show();
return a.exec();
}
Output:

Thank you so much for your answer. This also it works.
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QGraphicsView>
#include <QGraphicsTextItem>
#include <QGraphicsScene>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget *window = new QWidget;
window->resize(300, 200);
QVBoxLayout *layout = new QVBoxLayout(window);
QGraphicsScene *scene = new QGraphicsScene(window);
QGraphicsView *view = new QGraphicsView(scene);
QGraphicsTextItem *text = scene->addText("Hello World");
layout->addWidget(view);
window->show();
return a.exec();
}

Related

How to disable XCode compiler defines "-DXXX" in the Objective-C source code files

Tried #undef with NS_BLOCK_ASSERTIONS, but it looks like the Release default option from settings is welded brutally into the build process. The trick is to use only .m source code file directives (maybe pragmas) to disable it, because I'm in a situation where I have no control on XCode project settings and they are set as default for me in Release builds.
#undef NS_BLOCK_ASSERTIONS
#import <Foundation/Foundation.h>
#include <stdio.h>
#interface LoggingAssertionHandler : NSAssertionHandler
#end
#implementation LoggingAssertionHandler
- (void)handleFailureInMethod:(SEL)selector
object:(id)object
file:(NSString *)fileName
lineNumber:(NSInteger)line
description:(NSString *)format, ...
{
NSString *failureMessageDescription = [NSString stringWithFormat:#"NSAssert Failure: Method %# for object %# in %##%li. Reason: \"%#\"", NSStringFromSelector(selector), object, fileName, (long)line, format];
printf("%s\n", [failureMessageDescription UTF8String]);
}
- (void)handleFailureInFunction:(NSString *)functionName
file:(NSString *)fileName
lineNumber:(NSInteger)line
description:(NSString *)format, ...
{
NSString *failureMessageDescription = [NSString stringWithFormat:#"NSCAssert Failure: Function (%#) in %##%li. Reason: \"%#\"", functionName, fileName, (long)line, format];
printf("%s\n", [failureMessageDescription UTF8String]);
}
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSAssertionHandler *assertionHandler = [[LoggingAssertionHandler alloc] init];
[[[NSThread currentThread] threadDictionary] setValue:assertionHandler forKey:NSAssertionHandlerKey];
NSCAssert(true == false, #"Impossible.");
NSLog(#"Hello, World!");
}
return 0;
}
The problem is that the macros are part of the system files added at project creation, which are precompiled (pre-preprocessed). Your #undef is compiled later, therefore it cannot change the already preprocessed makros.
To change this, put the #undef in the .pch (precompiled headers) file ahead of the include of the system headers. It might look like this:
#ifdef __OBJC__
#undef NS_BLOCK_ASSERTIONS
#import <Cocoa/Cocoa.h>
#endif

How do I properly declare a global variable in a header file?

I was testing some code where I declare a global variable in a header file, but I'm getting a linker error: "duplicate symbol"
header file:
//
// GlobalVaraibleClass.h
// GlobalVar
//
#import <Foundation/Foundation.h>
int gGlobalVar = 0;
#interface GlobalVaraibleClass : NSObject
#end
class file:
//
// GlobalVaraibleClass.m
// GlobalVar
//
#import "GlobalVaraibleClass.h"
#implementation GlobalVaraibleClass
#end
main:
//
// main.m
// GlobalVar
//
#import <Foundation/Foundation.h>
#import "GlobalVaraibleClass.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
extern int gGlobalVar;
NSLog(#"Hello, World! %i", gGlobalVar);
}
return 0;
}
where am I going wrong?
That is backwards, the extern goes in the header, the declaration setting the value goes in the implementation file.
The extern specifies that the variable will be declared somewhere else. If the declaration is in the header every time the header is included there will be another declaration and at link time there will be multiple definitions which will not link.
Example:
// GlobalVaraibleClass.h
extern int gGlobalVar;
// GlobalVaraible.m
#import "GlobalVaraibleClass.h"
int gGlobalVar = 3;
// main.m
#import <Foundation/Foundation.h>
#import "GlobalVaraibleClass.h"
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSLog(#"Hello, World! %i", gGlobalVar);
}
return 0;
}

How can I TryParse userinput?

this is my problem:
#include "stdafx.h"
#include <iostream>
#include <string>
#define newline '\n'
using namespace std;
using namespace System;
int _tmain(int argc, _TCHAR* argv[])
{
bool isNumber;
String^ age;
Int32 result;
cout
<< "Please enter your age:"
<< newline;
cin >> age;
isNumber = Int32::TryParse(age, result);
return 0;
}
I cant use cin with a String^ and I can't use string to tryparse

QT run objective-c code

I'm trying to run native object-c code on my Mac application.
My code looks like:
MainWindow.h:
#ifdef Q_OS_MAC
#include <Carbon/Carbon.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <mach/mach_port.h>
#include <mach/mach_interface.h>
#include <mach/mach_init.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/IOMessage.h>
#endif
MainWindow.cpp:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
#ifdef Q_OS_MAC
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
selector: #selector(receiveSleepNote:)
name: NSWorkspaceWillSleepNotification object: NULL];
#endif
}
#ifdef Q_OS_MAC
- (void) receiveSleepNote: (NSNotification*) note
{
NSLog(#"receiveSleepNote: %#", [note name]);
}
#endif
But am getting errors that seems that QT does not understand the code structure:
application.cpp: error: expected external declaration
- (void) receiveSleepNote: (NSNotification*) note ^
In order to compile objective-c with C++, you need to have the objective-c code in a .m or .mm file.
The accompanying header can then contain functions that can be called from C++ and the body of those functions can contain objective-c code.
So let's say, for example, we wanted to call a function to pop up an OSX notification. Start with the header: -
#ifndef __MyNotification_h_
#define __MyNotification_h_
#include <QString>
class MyNotification
{
public:
static void Display(const QString& title, const QString& text);
};
#endif
As you can see, this is a regular function in a header that can be called from C++. Here's the implementation:-
#include "mynotification.h"
#import <Foundation/NSUserNotification.h>
#import <Foundation/NSString.h>
void MyNotification::Display(const QString& title, const QString& text)
{
NSString* titleStr = [[NSString alloc] initWithUTF8String:title.toUtf8().data()];
NSString* textStr = [[NSString alloc] initWithUTF8String:text.toUtf8().data()];
NSUserNotification* userNotification = [[[NSUserNotification alloc] init] autorelease];
userNotification.title = titleStr;
userNotification.informativeText = textStr;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:userNotification];
}
The implementation contains objective-c and due to its .mm file extension, the compiler will handle this correctly.
Note that in the example you provide in the question, you need to think about what the code is doing; especially when using 'self', as I expect that would need to refer to an Objective-C class, not a C++ class.

Properly use Objective C++

I'm coding an app for iOS and I recently #included a C++ header file in an Objective C implementation (.m) file. I changed the extension from .m to .mm and expected everything to run smoothly.
Unexpectedly I got multiple compiler errors in the .h file of my C++ class.
Such as: "C++ requires a type specifier for all declarations" and "Duplicate member...".
Does anyone know what could be causing this?
Edit - I've added the C++ header file for context:
#ifndef __CAAudioUnitOutputCapturer_h__
#define __CAAudioUnitOutputCapturer_h__
#include <AudioToolbox/ExtendedAudioFile.h>
/*
Class to capture output from an AudioUnit for analysis.
example:
CFURL fileurl = CFURLCreateWithFileSystemPath(NULL, CFSTR("/tmp/recording.caf"), kCFURLPOSIXPathStyle, false);
CAAudioUnitOutputCapturer captor(someAU, fileurl, 'caff', anASBD);
{
captor.Start();
...
captor.Stop();
} // can repeat
captor.Close(); // can be omitted; happens automatically from destructor
*/
class CAAudioUnitOutputCapturer {
public:
enum { noErr = 0 };
CAAudioUnitOutputCapturer(AudioUnit au, CFURLRef outputFileURL, AudioFileTypeID fileType, const AudioStreamBasicDescription &format, UInt32 busNumber = 0) :
mFileOpen(false),
mClientFormatSet(false),
mAudioUnit(au),
mExtAudioFile(NULL),
mBusNumber (busNumber)
{
CFShow(outputFileURL);
OSStatus err = ExtAudioFileCreateWithURL(outputFileURL, fileType, &format, NULL, kAudioFileFlags_EraseFile, &mExtAudioFile);
if (!err)
mFileOpen = true;
}
void Start() {
if (mFileOpen) {
if (!mClientFormatSet) {
AudioStreamBasicDescription clientFormat;
UInt32 size = sizeof(clientFormat);
AudioUnitGetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, mBusNumber, &clientFormat, &size);
ExtAudioFileSetProperty(mExtAudioFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);
mClientFormatSet = true;
}
ExtAudioFileWriteAsync(mExtAudioFile, 0, NULL); // initialize async writes
AudioUnitAddRenderNotify(mAudioUnit, RenderCallback, this);
}
}
void Stop() {
if (mFileOpen)
AudioUnitRemoveRenderNotify(mAudioUnit, RenderCallback, this);
}
void Close() {
if (mExtAudioFile) {
ExtAudioFileDispose(mExtAudioFile);
mExtAudioFile = NULL;
}
}
~CAAudioUnitOutputCapturer() {
Close();
}
private:
static OSStatus RenderCallback( void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData)
{
if (*ioActionFlags & kAudioUnitRenderAction_PostRender) {
CAAudioUnitOutputCapturer *This = (CAAudioUnitOutputCapturer *)inRefCon;
static int TEMP_kAudioUnitRenderAction_PostRenderError = (1 << 8);
if (This->mBusNumber == inBusNumber && !(*ioActionFlags & TEMP_kAudioUnitRenderAction_PostRenderError)) {
OSStatus result = ExtAudioFileWriteAsync(This->mExtAudioFile, inNumberFrames, ioData);
if (result) DebugMessageN1("ERROR WRITING FRAMES: %d\n", (int)result);
}
}
return noErr;
}
bool mFileOpen;
bool mClientFormatSet;
AudioUnit mAudioUnit;
ExtAudioFileRef mExtAudioFile;
UInt32 mBusNumber;
};
#endif // __CAAudioUnitOutputCapturer_h__
Unfortunately, if you just start making classes .mm, any class that uses that .mm's header will also need to become .mm. If you continue to just change your class extensions, you will eventually make the whole project Objective-c++. If that is your intention, then you can just change your build settings to compile for Objective-c++ (which could be a house of pain for you).
However, if you use some header magic, you will avoid a lot of hassle. Just make sure to change your Compile sources as build property to According to file type before compiling.
Here's something I did with a wrapper class I wrote to isolate a c++ class from the rest of my Objective-c classes. The c++ class is MyClass.
MyClassWrapper.h
//declare c++ impl for Obj-C++
#ifdef __cplusplus
class CppPlanterModel;
namespace com{namespace company{namespace mypackage {class MyClass;}}}
typedef com::company::mypackage::MyClass CppMyClass;
#endif
//declare obj-c impl
#ifdef __OBJC__
#ifndef __cplusplus
typedef void CppMyClass;
#endif
#endif
#interface MyClassWrapper : NSObject {
CppMyClass* _myClass;
}
//etc etc
#end
MyClassWrapper.mm
#include "MyClass.h"
using namespace com:company:mypackage;
class CppMyClass : public MyClass {
CppMyClass() {};
~CppMyClass() {};
//other stuff you might like to have
};
#implementation MyClassWrapper
//etc etc
#end
Here's another thing I did with a different header to handle sharing extern stuff:
Something.h
#ifdef __cplusplus
#define FV_EXTERN extern "C" __attribute__((visibility ("default")))
#else
#define FV_EXTERN extern __attribute__((visibility ("default")))
#endif
FV_EXTERN const int kMyInt;
FV_EXTERN int GetAnotherInt(...);
I recommend reading this blog entry about wrapping c++ (which also has links to other blog entries of a similar topic): http://robnapier.net/blog/wrapping-c-take-2-1-486
following the code at Rob Napier's blog I did it for CAAudioUnitOutputCapturer.
Thought I would share it to save other folks time.
RNWrap.h
//
// RNWrap.h
//
// ObjC wrapper for Wrap.cpp
//
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import <AudioUnit/AudioUnit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>
struct RNWrapOpaque;
#interface RNWrap : NSObject {
struct RNWrapOpaque *_cpp;
}
- (id) initWithAudioUnit:(AudioUnit) au andURL:(CFURLRef) outputFileURL andAudioFileTypeID:(AudioFileTypeID) fileType andAudioStreamBasicDescription: (const AudioStreamBasicDescription) asbd;
- (void) Start;
- (void) Close;
- (void) Stop;
#end
RNWrap.mm
//
// RNWrap.mm
// Objective C++ Wrapper Class for CAAudioUnitOutputCapturer.h
//
// Created by Pier 23/10/12
// Copyright 2012 DreamUpApps. All rights reserved.
//
#import "RNWrap.h"
#import "CAAudioUnitOutputCapturer.h"
#interface RNWrap ()
#property (nonatomic, readwrite, assign) RNWrapOpaque *cpp;
#end
#implementation RNWrap
#synthesize cpp = _cpp;
struct RNWrapOpaque
{
public:
RNWrapOpaque(AudioUnit au, CFURLRef outputFileURL, AudioFileTypeID fileType, const AudioStreamBasicDescription format) : outputCapturer(au, outputFileURL, fileType, format, 0) {}; // note added bus number = 0 at the end
CAAudioUnitOutputCapturer outputCapturer;
};
- (id)initWithAudioUnit:(AudioUnit) au andURL:(CFURLRef) outputFileURL andAudioFileTypeID:(AudioFileTypeID) fileType andAudioStreamBasicDescription: (const AudioStreamBasicDescription) format
{
self = [super init];
if (self != nil)
{
self.cpp = new RNWrapOpaque(au, outputFileURL, fileType, format);
}
return self;
}
- (void)dealloc
{
delete _cpp;
_cpp = NULL;
//[super dealloc];
}
- (void) Start
{
self.cpp->outputCapturer.Start();
}
- (void) Stop
{
self.cpp->outputCapturer.Stop();
}
- (void) Close
{
self.cpp->outputCapturer.Close();
}
#end
You use it like this in your class.
- (void) captureInAppAudio:(AudioUnit) auToCapture
{
AudioStreamBasicDescription destFormat;
memset( &destFormat, 0, sizeof(AudioStreamBasicDescription) );
destFormat.mSampleRate = 44100;
destFormat.mFormatID = kAudioFormatLinearPCM;
destFormat.mFormatFlags = ( kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagIsBigEndian );
destFormat.mBytesPerPacket = 2;
destFormat.mFramesPerPacket = 1;
destFormat.mBytesPerFrame = 2;
destFormat.mChannelsPerFrame = 1;
destFormat.mBitsPerChannel = 16;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
soundPath = [documentsDirectory stringByAppendingString:#"/recording.caf"] ;
CFURLRef fileurl = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)soundPath, kCFURLPOSIXPathStyle, false);
captor = [[RNWrap alloc] initWithAudioUnit:auToCapture andURL:fileurl andAudioFileTypeID:'caff' andAudioStreamBasicDescription:destFormat];
[captor Start];
}
Hope this helps someone else out there!
Pier.