├── qt.png ├── qmlapp.pro ├── ioscamera.h ├── main.cpp ├── Info.plist ├── ioscamera.mm └── main.qml /qt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardmg/qtdd13_qmlapp/HEAD/qt.png -------------------------------------------------------------------------------- /qmlapp.pro: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # Automatically generated by qmake (3.0) Wed Mar 6 15:34:02 2013 3 | ##################################################################### 4 | 5 | TEMPLATE = app 6 | TARGET = QmlApp 7 | INCLUDEPATH += . 8 | QT += quick sensors gui_private 9 | 10 | QMAKE_INFO_PLIST = Info.plist 11 | 12 | SOURCES += main.cpp 13 | RESOURCES += main.qml qt.png 14 | 15 | HEADERS += \ 16 | ioscamera.h 17 | 18 | OBJECTIVE_SOURCES += \ 19 | ioscamera.mm 20 | -------------------------------------------------------------------------------- /ioscamera.h: -------------------------------------------------------------------------------- 1 | #ifndef IOSCAMERA_H 2 | #define IOSCAMERA_H 3 | 4 | #include 5 | 6 | class IOSCamera : public QQuickItem 7 | { 8 | Q_OBJECT 9 | Q_PROPERTY(QString imagePath READ imagePath NOTIFY imagePathChanged) 10 | 11 | public: 12 | explicit IOSCamera(QQuickItem *parent = 0); 13 | 14 | QString imagePath() { 15 | return m_imagePath; 16 | } 17 | 18 | QString m_imagePath; 19 | 20 | signals: 21 | void imagePathChanged(); 22 | 23 | public slots: 24 | void open(); 25 | 26 | private: 27 | void *m_delegate; 28 | }; 29 | 30 | #endif // IOSCAMERA_H 31 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ioscamera.h" 3 | 4 | int main(int argc, char **argv) 5 | { 6 | QGuiApplication app(argc, argv); 7 | app.primaryScreen()->setOrientationUpdateMask(Qt::PortraitOrientation | Qt::LandscapeOrientation); 8 | 9 | qmlRegisterType("IOSCamera", 1, 0, "IOSCamera"); 10 | 11 | QQmlEngine engine; 12 | QQmlComponent component(&engine); 13 | component.loadUrl(QUrl("qrc:/main.qml")); 14 | QQuickWindow* window = qobject_cast(component.create()); 15 | window->show(); 16 | 17 | return app.exec(); 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | ${PRODUCT_NAME} 7 | CFBundleExecutable 8 | QmlApp 9 | CFBundleGetInfoString 10 | Created by Qt/QMake 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | qt.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | NOTE 26 | This file was generated by Qt/QMake. 27 | NSCameraUsageDescription 28 | Uses camera 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /ioscamera.mm: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "ioscamera.h" 8 | 9 | @interface CameraDelegate : NSObject { 10 | IOSCamera *m_iosCamera; 11 | } 12 | @end 13 | 14 | @implementation CameraDelegate 15 | 16 | - (id) initWithIOSCamera:(IOSCamera *)iosCamera 17 | { 18 | self = [super init]; 19 | if (self) { 20 | m_iosCamera = iosCamera; 21 | } 22 | return self; 23 | } 24 | 25 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 26 | { 27 | Q_UNUSED(picker); 28 | 29 | // Create the path where we want to save the image: 30 | NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 31 | path = [path stringByAppendingString:@"/capture.png"]; 32 | 33 | // Save image: 34 | UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; 35 | [UIImagePNGRepresentation(image) writeToFile:path options:NSAtomicWrite error:nil]; 36 | 37 | // Update imagePath property to trigger QML code: 38 | m_iosCamera->m_imagePath = QStringLiteral("file:") + QString::fromNSString(path); 39 | emit m_iosCamera->imagePathChanged(); 40 | 41 | // Bring back Qt's view controller: 42 | UIViewController *rvc = [[[UIApplication sharedApplication] keyWindow] rootViewController]; 43 | [rvc dismissViewControllerAnimated:YES completion:nil]; 44 | } 45 | 46 | @end 47 | 48 | IOSCamera::IOSCamera(QQuickItem *parent) : 49 | QQuickItem(parent), m_delegate([[CameraDelegate alloc] initWithIOSCamera:this]) 50 | { 51 | } 52 | 53 | void IOSCamera::open() 54 | { 55 | // Get the UIView that backs our QQuickWindow: 56 | UIView *view = static_cast( 57 | QGuiApplication::platformNativeInterface() 58 | ->nativeResourceForWindow("uiview", window())); 59 | UIViewController *qtController = [[view window] rootViewController]; 60 | 61 | // Create a new image picker controller to show on top of Qt's view controller: 62 | UIImagePickerController *imageController = [[[UIImagePickerController alloc] init] autorelease]; 63 | [imageController setSourceType:UIImagePickerControllerSourceTypeCamera]; 64 | [imageController setDelegate:id(m_delegate)]; 65 | 66 | // Tell the imagecontroller to animate on top: 67 | [qtController presentViewController:imageController animated:YES completion:nil]; 68 | } 69 | -------------------------------------------------------------------------------- /main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QtQuick.Window 2.0 3 | import QtSensors 5.1 4 | import IOSCamera 1.0 5 | 6 | Window { 7 | id: mainWindow 8 | color: "white" 9 | 10 | IOSCamera { 11 | id: camera 12 | onImagePathChanged: { 13 | // The captured image has changed. But since the path stays the 14 | // same if you take several snapshots, we clear the source first 15 | // to force a reload. 16 | img.source = "" 17 | img.source = imagePath 18 | } 19 | } 20 | 21 | Accelerometer { 22 | id: sensor 23 | active: Qt.application.state === Qt.ApplicationActive 24 | } 25 | 26 | Image { 27 | id: img 28 | width: 200 29 | height: 200 30 | source: "qt.png" 31 | rotation: Screen.orientation === Qt.PortraitOrientation ? 0 : -90 32 | Behavior on rotation { 33 | NumberAnimation { 34 | duration: 1000 35 | easing.type: Easing.OutBounce 36 | } 37 | } 38 | 39 | MouseArea { 40 | anchors.fill: parent 41 | onClicked: camera.open() 42 | } 43 | 44 | property real speedX: 0 45 | property real speedY: 0 46 | property real friction: 0.05 47 | property real bounce: 0.6 48 | property real gravity: 0.2 49 | 50 | property real tick: 0 51 | NumberAnimation on tick { to: 1; duration: Number.MAX_VALUE; paused: !sensor.active } 52 | 53 | onTickChanged: 54 | { 55 | // Adjust icon speed: 56 | speedX -= sensor.reading.x * gravity; 57 | speedY += sensor.reading.y * gravity 58 | 59 | // Calculate where the icon should be: 60 | x += (speedX > 0) ? Math.max(0, speedX - friction) : Math.min(0, speedX + friction); 61 | y += (speedY > 0) ? Math.max(0, speedY - friction) : Math.min(0, speedY + friction) 62 | 63 | // Bounce icon back in if outside screen: 64 | if (x < 0) { 65 | x = 0 66 | speedX = speedX * -1 * bounce 67 | } else if (x > mainWindow.width - paintedWidth) { 68 | x = mainWindow.width - paintedWidth 69 | speedX = speedX * -1 * bounce 70 | } 71 | 72 | if (y < 0) { 73 | y = 0 74 | speedY = speedY * -1 * bounce 75 | } 76 | 77 | if (y > mainWindow.height - paintedHeight) { 78 | y = mainWindow.height - paintedHeight 79 | speedY = speedY * -1 * bounce 80 | } 81 | } 82 | 83 | } 84 | } 85 | --------------------------------------------------------------------------------