2013-02-26 23 views
5

Tôi đang tìm một cách hay để giải quyết việc chuyển các ứng dụng Qt sang Qt/Necessitas (Android).Qt/Necessitas - thay thế/da QFileDialog hợp lý?

Một số tiện ích QtGUI cực kỳ nguy hiểm - không may, kể cả QFileDialog.

Bạn có biết bất kỳ sự thay thế nào có giao diện phù hợp không? Làm cho QFileDialog có thể sử dụng được ở bất kỳ nơi nào gần mức độ ưu tiên cao cho các nhà phát triển Necessitas không?

#include <QApplication> 

#include <QFileDialog> 

int main(int argc, char* argv[]) { 
    QApplication a(argc, argv); 

    QString fileName = QFileDialog::getOpenFileName(NULL, 
     QObject::tr("Open Image"), "/home/jana", QObject::tr("Image Files (*.png *.jpg *.bmp)")); 

    a.exec(); 
} 

QFileDialog

+0

Ý của bạn là gì - tẻ nhạt? Điều này là hoàn toàn trơn! – mlvljr

Trả lời

1

Bạn có thể dễ dàng xây dựng thoại tập tin riêng của bạn, hoặc với QtWidgets hoặc QML, bằng cách sử dụng các out-of-the-box QFileSystemModel lớp.

Cho dù đó là ưu tiên hay không, tại thời điểm này có vẻ như Necessitas sẽ được Digia hỗ trợ để hỗ trợ Android. Tôi nghi ngờ sẽ có những nỗ lực đáng kể để tạo kiểu QtWidgets một cách thích hợp, vì mô-đun được đánh dấu là XONG và tất cả tiêu điểm cho giao diện người dùng là trên QML. Vì vậy, tôi sẽ không nín thở nếu tôi là bạn. Cộng với tiện ích con Qt cổ phiếu trông hoàn toàn xấu xí trên nền tảng không phải máy tính để bàn.

3

Android không có hộp thoại tệp gốc. Chúng ta có thể sử dụng QtAndroidExtras để gọi ứng dụng bên ngoài mà có thể chọn một tập tin:

chosing external application

tôi đã viết wrapper, mà có thể được sử dụng cho điều đó. Đây là mã đầy đủ:

androidfiledialog.h

#ifndef ANDROIDFILEDIALOG_H 
#define ANDROIDFILEDIALOG_H 

#include <QObject> 
#include <QAndroidJniObject> 
#include <QtAndroid> 
#include <QAndroidActivityResultReceiver> 

class AndroidFileDialog : public QObject 
{ 
    Q_OBJECT 

public: 
    explicit AndroidFileDialog(QObject *parent = 0); 
    virtual ~AndroidFileDialog(); 
    bool provideExistingFileName(); 

private: 
    class ResultReceiver : public QAndroidActivityResultReceiver { 
     AndroidFileDialog *_dialog; 
    public: 
     ResultReceiver(AndroidFileDialog *dialog); 
     virtual ~ResultReceiver(); 
     void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data); 
     QString uriToPath(QAndroidJniObject uri); 
    }; 

    static const int EXISTING_FILE_NAME_REQUEST = 1; 
    ResultReceiver *receiver; 
    void emitExistingFileNameReady(QString result); 

signals: 
    void existingFileNameReady(QString result); 
}; 

#endif // ANDROIDFILEDIALOG_H 

androidfiledialog.cpp

#include "androidfiledialog.h" 

AndroidFileDialog::ResultReceiver::ResultReceiver(AndroidFileDialog *dialog) : _dialog(dialog) {} 
AndroidFileDialog::ResultReceiver::~ResultReceiver() {} 

void AndroidFileDialog::ResultReceiver::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) 
{ 
    jint RESULT_OK = QAndroidJniObject::getStaticField<jint>("android/app/Activity", "RESULT_OK"); 
    if (receiverRequestCode == EXISTING_FILE_NAME_REQUEST && resultCode == RESULT_OK) { 
     QAndroidJniObject uri = data.callObjectMethod("getData", "()Landroid/net/Uri;"); 
     QString path = uriToPath(uri); 
     _dialog->emitExistingFileNameReady(path); 
    } else { 
     _dialog->emitExistingFileNameReady(QString()); 
    } 
} 

QString AndroidFileDialog::ResultReceiver::uriToPath(QAndroidJniObject uri) 
{ 
    if (uri.toString().startsWith("file:", Qt::CaseInsensitive)) { 
     return uri.callObjectMethod("getPath", "()Ljava/lang/String;").toString(); 
    } else { 
     QAndroidJniObject contentResolver = QtAndroid::androidActivity().callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;"); 
     QAndroidJniObject cursor = contentResolver.callObjectMethod("query", "(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;", uri.object<jobject>(), 0, 0, 0, 0); 
     QAndroidJniObject DATA = QAndroidJniObject::fromString("_data"); 
     jint columnIndex = cursor.callMethod<jint>("getColumnIndexOrThrow", "(Ljava/lang/String;)I", DATA.object<jstring>()); 
     cursor.callMethod<jboolean>("moveToFirst", "()Z"); 
     QAndroidJniObject result = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex); 
     return result.isValid() ? result.toString() : QString(); 
    } 
} 

AndroidFileDialog::AndroidFileDialog(QObject *parent) : QObject(parent) 
{ 
    receiver = new ResultReceiver(this); 
} 

AndroidFileDialog::~AndroidFileDialog() 
{ 
    delete receiver; 
} 

bool AndroidFileDialog::provideExistingFileName() 
{ 
    QAndroidJniObject ACTION_GET_CONTENT = QAndroidJniObject::fromString("android.intent.action.GET_CONTENT"); 
    QAndroidJniObject intent("android/content/Intent"); 
    if (ACTION_GET_CONTENT.isValid() && intent.isValid()) { 
     intent.callObjectMethod("setAction", "(Ljava/lang/String;)Landroid/content/Intent;", ACTION_GET_CONTENT.object<jstring>()); 
     intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("file/*").object<jstring>()); 
     QtAndroid::startActivity(intent.object<jobject>(), EXISTING_FILE_NAME_REQUEST, receiver); 
     return true; 
    } else { 
     return false; 
    } 
} 

void AndroidFileDialog::emitExistingFileNameReady(QString result) 
{ 
    emit existingFileNameReady(result); 
} 

Bạn cần phải thêm vào file * .pro của bạn:

QT += androidextras 

sử dụng ví dụ:

AndroidFileDialog *fileDialog = new AndroidFileDialog(); 
connect(fileDialog, SIGNAL(existingFileNameReady(QString)), this, SLOT(openFileNameReady(QString))); 
bool success = fileDialog->provideExistingFileName(); 
if (!success) { 
    qDebug() << "Problem with JNI or sth like that..."; 
    disconnect(fileDialog, SIGNAL(existingFileNameReady(QString)), this, SLOT(openFileNameReady(QString))); 
    //or just delete fileDialog instead of disconnect 
} 

thực hiện khe:

void MyClass::openFileNameReady(QString fileName) 
{ 
    if (!fileName.isNull()) { 
     qDebug() << "FileName: " << fileName; 
    } else { 
     qDebug() << "User did not choose file"; 
    } 
} 

Vui lòng xác nhận giải pháp này hoạt động đúng trên thiết bị của bạn.