2009-06-03 28 views
6

Tôi đã thêm thành công đối tượng C++ vào QWebFrame với addToJavaScriptWindowObject, và có thể gọi một vị trí trên đối tượng đó từ javascript.Làm thế nào để có được Javascript trong một QWebView để tạo ra các cá thể mới của các lớp dựa trên C++?

Nhưng những gì tôi thực sự muốn làm là có một trong những vị trí đó trả về một đối tượng mới. Ví dụ, tôi có một khe cắm như thế này, mà trả về một thể hiện lớp QObject có nguồn gốc:

MyObject* MyApp::helloWorld() 
    { 
      //MyObject is dervied from QObject 
      return new MyObject(); 
    } 

tôi có thể gọi khe này từ javascript thành công như thế này

var foo=myapp.helloWorld(); 

Nhưng foo dường như là trống rỗng, tôi không thể gọi bất kỳ vị trí nào hoặc truy cập bất kỳ thuộc tính nào từ Javascript.

Bất kỳ ý tưởng nào về cách tôi có thể đạt được điều này?

+0

Trong câu hỏi bạn muốn nói là MyApp :: helloWorld, phải không? – jrharshath

+0

Vâng, được phát hiện rõ ràng :) –

Trả lời

4

Một Hack khá xấu xí tôi đã coi là sử dụng addToJavaScriptWindowObject để thả các đối tượng tôi muốn quay trở lại vào đối tượng cửa sổ với một tên ngẫu nhiên, sau đó có khe tôi lại hiện ra tên của trường hợp đối tượng thay vì:

QString MyApp::helloWorld() 
{ 
    //general a unique name for the js variable 
    QString name=getRandomVariableName(); 

    //here's the object we want to expose to js 
    MyObject* pReturn=new MyObject(); 

    //we make attach our object to the js window object  
    getWebFrame()->addToJavaScriptWindowObject(name, pReturn, 
     QScriptEngine::ScriptOwnership); 

    //tell js the name we used 
    return name; 
} 

các JS có thể được viết để kiểm tra xem giá trị trả về là một chuỗi, và nếu nó là, lấy đối tượng từ cửa sổ .:

var foo=myapp.helloWorld(); 
if (typeof foo == "string") 
{ 
    foo=window[foo]; 
} 

một chút xấu xí, nhưng sẽ làm cho tôi bởi cho đến khi một tốt hơn phương pháp đi kèm. Các phiên bản Qt trong tương lai sẽ thống nhất hỗ trợ kịch bản để tất cả đều dựa trên JavaScriptCore trong WebKit, vì vậy hy vọng điều này sẽ cải thiện sau đó!

1

QtScript có khái niệm nguyên mẫu - cho phép bạn tạo một nguyên mẫu C++ cho giá trị tập lệnh. Chúng tôi đang điều tra thời tiết, chúng tôi có thể kết nối QtScript với JavaScriptCore - mà nên dẫn đến khả năng sử dụng nguyên mẫu từ môi trường JavaScript của WebKit; http://doc.trolltech.com/4.5/qtscript.html#making-use-of-prototype-based-inheritance

+0

Có, tôi thấy rằng một số sự thống nhất trên lộ trình, điều này sẽ rất tuyệt. Tôi đã mananged để ẩn "xấu xí" của workaround của tôi anyway, do đó, các js tôi viết sẽ vẫn còn phần lớn có thể sử dụng khi một giải pháp tốt hơn đến cùng. –

1

Thử trả lại đối tượng mới của bạn dưới dạng QObject * thay vì MyObject *. Nếu bạn chỉ làm việc với QtScript, thì bạn có thể gọi qScriptRegisterMetaType để xác định một số mã để xử lý chuyển đổi MyObject * thành QScriptValues ​​(hoặc QVariants), nhưng dường như không tương đương với công cụ JavaScript được sử dụng trong QtWebKit.

Điều này có nghĩa là việc hiển thị mô hình đối tượng nội bộ của bạn với WebKit sẽ liên quan đến việc có một bộ chức năng proxy riêng biệt chuyển đổi con trỏ đối tượng thành QObject * s hoặc sử dụng các lớp bộ điều hợp.

+0

Thật vậy, những gì tôi đã làm với các lớp học adapter trong cả C++ và JS để thu hẹp khoảng cách và để cho JS "thực" cảm thấy như mọi thứ đang xảy ra như nó cần. –

2

Bạn có thể gán con trỏ đối tượng của mình cho QObject * và trả về điều đó.

QObject * obj = new MyObject(); 
    return obj; 

Điều đó đang làm việc cho tôi trên cổng Qt Webkit trên Linux.

0

Câu trả lời này dựa trên câu trả lời của Paul, nhưng được đơn giản hóa một chút. Thử nghiệm và làm việc cho Qt 5.3. Bạn cần một nhà máy instantiates một đối tượng, và sau đó trả về một con trỏ QObject cho đối tượng này.lớp của đối tượng phải kế thừa từ QObject để nó hoạt động đúng trong JavaScript:

QObject * MyApp::createInstance(QString objname) { 
    MyClass * obj = new MyClass(this); 
    m_mainWindow->webView->page()->mainFrame()->addToJavaScriptWindowObject(objname, obj, QWebFrame::ScriptOwnership); 
    return obj; 
} 

Với điều này, bạn có thể làm như sau từ javascript:

var myobject = MyApp.createInstance("obj1"); 

Tại thời điểm này, bạn có obj1 cũng dưới dạng myobject trong không gian tên JavaScript chung (chúng chỉ là con trỏ, do đó, hãy thực hiện cả hai công việc sau:

myobject.testmethod(); 
obj1.testmethod(); 

Tại điểm này, bạn có thể sử dụng connect trong JavaScript để kết nối tín hiệu C++ với các vùng JavaScript. Thông tin thêm về kỹ thuật này tại đây: http://doc.qt.io/qt-5/qtwebkit-bridge.html

Các vấn đề liên quan