Tweaks and fixes + added webview debugger
* Require better icons .. someone? :-)
This commit is contained in:
parent
d518423b9c
commit
95ba340d07
Binary file not shown.
After Width: | Height: | Size: 931 B |
Binary file not shown.
After Width: | Height: | Size: 905 B |
|
@ -2,30 +2,97 @@
|
|||
window.eth = {
|
||||
prototype: Object(),
|
||||
|
||||
mutan: function(code) {
|
||||
},
|
||||
|
||||
toHex: function(str) {
|
||||
var hex = "";
|
||||
for(var i = 0; i < str.length; i++) {
|
||||
var n = str.charCodeAt(i).toString(16);
|
||||
hex += n.length < 2 ? '0' + n : n;
|
||||
}
|
||||
|
||||
return hex;
|
||||
},
|
||||
|
||||
toAscii: function(hex) {
|
||||
// Find termination
|
||||
var str = "";
|
||||
var i = 0, l = hex.length;
|
||||
for(; i < l; i+=2) {
|
||||
var code = hex.charCodeAt(i)
|
||||
if(code == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
|
||||
fromAscii: function(str, pad) {
|
||||
if(pad === undefined) {
|
||||
pad = 32
|
||||
}
|
||||
|
||||
var hex = this.toHex(str);
|
||||
|
||||
while(hex.length < pad*2)
|
||||
hex += "00";
|
||||
|
||||
return hex
|
||||
},
|
||||
|
||||
|
||||
// Retrieve block
|
||||
//
|
||||
// Either supply a number or a string. Type is determent for the lookup method
|
||||
// string - Retrieves the block by looking up the hash
|
||||
// number - Retrieves the block by looking up the block number
|
||||
getBlock: function(numberOrHash, cb) {
|
||||
var func;
|
||||
if(typeof numberOrHash == "string") {
|
||||
func = "getBlockByHash";
|
||||
} else {
|
||||
func = "getBlockByNumber";
|
||||
}
|
||||
postData({call: func, args: [numberOrHash]}, cb);
|
||||
},
|
||||
getBlock: function(numberOrHash, cb) {
|
||||
var func;
|
||||
if(typeof numberOrHash == "string") {
|
||||
func = "getBlockByHash";
|
||||
} else {
|
||||
func = "getBlockByNumber";
|
||||
}
|
||||
postData({call: func, args: [numberOrHash]}, cb);
|
||||
},
|
||||
|
||||
// Create transaction
|
||||
//
|
||||
// Transact between two state objects
|
||||
transact: function(sec, recipient, value, gas, gasPrice, data, cb) {
|
||||
postData({call: "transact", args: [sec, recipient, value, gas, gasPrice, data]}, cb);
|
||||
},
|
||||
transact: function(params, cb) {
|
||||
if(params === undefined) {
|
||||
params = {};
|
||||
}
|
||||
|
||||
create: function(sec, value, gas, gasPrice, init, body, cb) {
|
||||
postData({call: "create", args: [sec, value, gas, gasPrice, init, body]}, cb);
|
||||
if(params.endowment !== undefined)
|
||||
params.value = params.endowment;
|
||||
if(params.code !== undefined)
|
||||
params.data = params.code;
|
||||
|
||||
// Make sure everything is string
|
||||
var fields = ["to", "from", "value", "gas", "gasPrice"];
|
||||
for(var i = 0; i < fields.length; i++) {
|
||||
if(params[fields[i]] === undefined) {
|
||||
params[fields[i]] = "";
|
||||
}
|
||||
params[fields[i]] = params[fields[i]].toString();
|
||||
}
|
||||
|
||||
var data;
|
||||
if(typeof params.data === "object") {
|
||||
data = "";
|
||||
for(var i = 0; i < params.data.length; i++) {
|
||||
data += params.data[i]
|
||||
}
|
||||
} else {
|
||||
data = params.data;
|
||||
}
|
||||
|
||||
postData({call: "transact", args: [params.from, params.to, params.value, params.gas, params.gasPrice, "0x"+data]}, cb);
|
||||
},
|
||||
|
||||
getStorageAt: function(address, storageAddress, cb) {
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
function handleMessage(message) {
|
||||
console.log("[onMessageReceived]: ", message.data)
|
||||
// TODO move to messaging.js
|
||||
var data = JSON.parse(message.data)
|
||||
|
||||
try {
|
||||
switch(data.call) {
|
||||
case "getCoinBase":
|
||||
postData(data._seed, eth.getCoinBase())
|
||||
|
||||
break
|
||||
case "getIsListening":
|
||||
postData(data._seed, eth.getIsListening())
|
||||
|
||||
break
|
||||
case "getIsMining":
|
||||
postData(data._seed, eth.getIsMining())
|
||||
|
||||
break
|
||||
case "getPeerCount":
|
||||
postData(data._seed, eth.getPeerCount())
|
||||
|
||||
break
|
||||
|
||||
case "getTxCountAt":
|
||||
require(1)
|
||||
postData(data._seed, eth.getTxCountAt(data.args[0]))
|
||||
|
||||
break
|
||||
case "getBlockByNumber":
|
||||
var block = eth.getBlock(data.args[0])
|
||||
postData(data._seed, block)
|
||||
|
||||
break
|
||||
case "getBlockByHash":
|
||||
var block = eth.getBlock(data.args[0])
|
||||
postData(data._seed, block)
|
||||
|
||||
break
|
||||
case "transact":
|
||||
require(5)
|
||||
|
||||
var tx = eth.transact(data.args[0], data.args[1], data.args[2],data.args[3],data.args[4],data.args[5])
|
||||
postData(data._seed, tx)
|
||||
|
||||
break
|
||||
case "create":
|
||||
postData(data._seed, null)
|
||||
|
||||
break
|
||||
case "getStorage":
|
||||
require(2);
|
||||
|
||||
var stateObject = eth.getStateObject(data.args[0])
|
||||
var storage = stateObject.getStorage(data.args[1])
|
||||
postData(data._seed, storage)
|
||||
|
||||
break
|
||||
case "getStateKeyVals":
|
||||
require(1);
|
||||
var stateObject = eth.getStateObject(data.args[0]).stateKeyVal(true)
|
||||
postData(data._seed,stateObject)
|
||||
|
||||
break
|
||||
case "getTransactionsFor":
|
||||
require(1);
|
||||
var txs = eth.getTransactionsFor(data.args[0], true)
|
||||
postData(data._seed, txs)
|
||||
|
||||
break
|
||||
case "getBalance":
|
||||
require(1);
|
||||
|
||||
postData(data._seed, eth.getStateObject(data.args[0]).value());
|
||||
|
||||
break
|
||||
case "getKey":
|
||||
var key = eth.getKey().privateKey;
|
||||
|
||||
postData(data._seed, key)
|
||||
break
|
||||
case "watch":
|
||||
require(1)
|
||||
eth.watch(data.args[0], data.args[1]);
|
||||
break
|
||||
case "disconnect":
|
||||
require(1)
|
||||
postData(data._seed, null)
|
||||
break;
|
||||
case "set":
|
||||
console.log("'Set' has been depcrecated")
|
||||
/*
|
||||
for(var key in data.args) {
|
||||
if(webview.hasOwnProperty(key)) {
|
||||
window[key] = data.args[key];
|
||||
}
|
||||
}
|
||||
*/
|
||||
break;
|
||||
case "getSecretToAddress":
|
||||
require(1)
|
||||
postData(data._seed, eth.secretToAddress(data.args[0]))
|
||||
break;
|
||||
case "debug":
|
||||
console.log(data.args[0]);
|
||||
break;
|
||||
}
|
||||
} catch(e) {
|
||||
console.log(data.call + ": " + e)
|
||||
|
||||
postData(data._seed, null);
|
||||
}
|
||||
}
|
||||
|
||||
function postData(seed, data) {
|
||||
webview.experimental.postMessage(JSON.stringify({data: data, _seed: seed}))
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 932 B |
|
@ -29,7 +29,7 @@ Rectangle {
|
|||
model: txModel
|
||||
}
|
||||
|
||||
function addTx(type, tx, inout) {
|
||||
function addTx(tx, inout) {
|
||||
var isContract
|
||||
if (tx.contract == true){
|
||||
isContract = "Yes"
|
||||
|
|
|
@ -17,6 +17,7 @@ Rectangle {
|
|||
color: "#00000000"
|
||||
|
||||
Column {
|
||||
id: info
|
||||
spacing: 3
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 5
|
||||
|
@ -49,7 +50,7 @@ Rectangle {
|
|||
}
|
||||
TableView {
|
||||
id: addressView
|
||||
width: parent.width - 200
|
||||
width: parent.width
|
||||
height: 200
|
||||
anchors.bottom: logLayout.top
|
||||
TableViewColumn{ role: "name"; title: "name" }
|
||||
|
@ -58,30 +59,6 @@ Rectangle {
|
|||
model: addressModel
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.top: addressView.top
|
||||
anchors.left: addressView.right
|
||||
anchors.leftMargin: 20
|
||||
|
||||
TextField {
|
||||
placeholderText: "Name to register"
|
||||
id: nameToReg
|
||||
width: 150
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.top: nameToReg.bottom
|
||||
text: "Register"
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
gui.registerName(nameToReg.text)
|
||||
nameToReg.text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property var logModel: ListModel {
|
||||
id: logModel
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.0;
|
||||
import QtQuick.Layouts 1.0;
|
||||
import QtQuick.Dialogs 1.0;
|
||||
import QtQuick.Window 2.1;
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
import Ethereum 1.0
|
||||
|
||||
Rectangle {
|
||||
property var title: "JavaScript"
|
||||
property var iconFile: "../tx.png"
|
||||
|
||||
objectName: "javascriptView"
|
||||
visible: false
|
||||
anchors.fill: parent
|
||||
|
||||
TextField {
|
||||
id: input
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
height: 20
|
||||
|
||||
Keys.onReturnPressed: {
|
||||
var res = eth.evalJavascriptString(this.text);
|
||||
this.text = "";
|
||||
|
||||
output.append(res)
|
||||
}
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: output
|
||||
verticalAlignment: TextEdit.AlignBottom
|
||||
text: "> JSRE Ready..."
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: input.top
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,7 +30,7 @@ Rectangle {
|
|||
model: pendingTxModel
|
||||
}
|
||||
|
||||
function addTx(type, tx, inout) {
|
||||
function addTx(tx, inout) {
|
||||
var isContract
|
||||
if (tx.contract == true){
|
||||
isContract = "Yes"
|
||||
|
|
|
@ -24,6 +24,7 @@ ApplicationWindow {
|
|||
var chainView = addPlugin("./views/chain.qml", {title: "Block chain"})
|
||||
var infoView = addPlugin("./views/info.qml", {title: "Info"})
|
||||
var pendingTxView = addPlugin("./views/pending_tx.qml", {title: "Pending", canClose: true})
|
||||
var pendingTxView = addPlugin("./views/javascript.qml", {title: "JavaScript", canClose: true})
|
||||
|
||||
// Call the ready handler
|
||||
gui.done()
|
||||
|
@ -259,8 +260,8 @@ ApplicationWindow {
|
|||
********************/
|
||||
Rectangle {
|
||||
id: menu
|
||||
Layout.minimumWidth: 180
|
||||
Layout.maximumWidth: 180
|
||||
Layout.minimumWidth: 80
|
||||
Layout.maximumWidth: 80
|
||||
anchors.top: parent.top
|
||||
color: "#252525"
|
||||
|
||||
|
@ -398,9 +399,9 @@ ApplicationWindow {
|
|||
function importApp(path) {
|
||||
var ext = path.split('.').pop()
|
||||
if(ext == "html" || ext == "htm") {
|
||||
ui.openHtml(path)
|
||||
eth.openHtml(path)
|
||||
}else if(ext == "qml"){
|
||||
ui.openQml(path)
|
||||
eth.openQml(path)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,46 +21,62 @@ ApplicationWindow {
|
|||
id: root
|
||||
anchors.fill: parent
|
||||
state: "inspectorShown"
|
||||
TextField {
|
||||
|
||||
RowLayout {
|
||||
id: navBar
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
id: uriNav
|
||||
//text: webview.url
|
||||
|
||||
Keys.onReturnPressed: {
|
||||
var uri = this.text;
|
||||
if(!/.*\:\/\/.*/.test(uri)) {
|
||||
uri = "http://" + uri;
|
||||
Button {
|
||||
id: back
|
||||
iconSource: "../back.png"
|
||||
onClicked: {
|
||||
webview.goBack()
|
||||
}
|
||||
}
|
||||
|
||||
var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/
|
||||
|
||||
if(reg.test(uri)) {
|
||||
this.text.replace(reg, function(match, pre, domain, path) {
|
||||
uri = pre;
|
||||
|
||||
var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4));
|
||||
var ip = [];
|
||||
for(var i = 0, l = lookup.length; i < l; i++) {
|
||||
ip.push(lookup.charCodeAt(i))
|
||||
}
|
||||
|
||||
if(ip.length != 0) {
|
||||
uri += lookup;
|
||||
} else {
|
||||
uri += domain;
|
||||
}
|
||||
|
||||
uri += path;
|
||||
});
|
||||
TextField {
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: back.right
|
||||
right: parent.right
|
||||
}
|
||||
id: uriNav
|
||||
|
||||
console.log("connecting to ...", uri)
|
||||
Keys.onReturnPressed: {
|
||||
var uri = this.text;
|
||||
if(!/.*\:\/\/.*/.test(uri)) {
|
||||
uri = "http://" + uri;
|
||||
}
|
||||
|
||||
webview.url = uri;
|
||||
var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/
|
||||
|
||||
if(reg.test(uri)) {
|
||||
this.text.replace(reg, function(match, pre, domain, path) {
|
||||
uri = pre;
|
||||
|
||||
var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4));
|
||||
var ip = [];
|
||||
for(var i = 0, l = lookup.length; i < l; i++) {
|
||||
ip.push(lookup.charCodeAt(i))
|
||||
}
|
||||
|
||||
if(ip.length != 0) {
|
||||
uri += lookup;
|
||||
} else {
|
||||
uri += domain;
|
||||
}
|
||||
|
||||
uri += path;
|
||||
});
|
||||
}
|
||||
|
||||
console.log("connecting to ...", uri)
|
||||
|
||||
webview.url = uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,7 +87,7 @@ ApplicationWindow {
|
|||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
top: uriNav.bottom
|
||||
top: navBar.bottom
|
||||
}
|
||||
onTitleChanged: { window.title = title }
|
||||
experimental.preferences.javascriptEnabled: true
|
||||
|
@ -86,103 +102,107 @@ ApplicationWindow {
|
|||
try {
|
||||
switch(data.call) {
|
||||
case "getCoinBase":
|
||||
postData(data._seed, eth.getCoinBase())
|
||||
postData(data._seed, eth.getCoinBase())
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
case "getIsListening":
|
||||
postData(data._seed, eth.getIsListening())
|
||||
postData(data._seed, eth.getIsListening())
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
case "getIsMining":
|
||||
postData(data._seed, eth.getIsMining())
|
||||
postData(data._seed, eth.getIsMining())
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
case "getPeerCount":
|
||||
postData(data._seed, eth.getPeerCount())
|
||||
postData(data._seed, eth.getPeerCount())
|
||||
|
||||
break
|
||||
break
|
||||
|
||||
case "getTxCountAt":
|
||||
require(1)
|
||||
postData(data._seed, eth.getTxCountAt(data.args[0]))
|
||||
require(1)
|
||||
postData(data._seed, eth.getTxCountAt(data.args[0]))
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
case "getBlockByNumber":
|
||||
var block = eth.getBlock(data.args[0])
|
||||
postData(data._seed, block)
|
||||
var block = eth.getBlock(data.args[0])
|
||||
postData(data._seed, block)
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
case "getBlockByHash":
|
||||
var block = eth.getBlock(data.args[0])
|
||||
postData(data._seed, block)
|
||||
var block = eth.getBlock(data.args[0])
|
||||
postData(data._seed, block)
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
case "transact":
|
||||
require(5)
|
||||
require(5)
|
||||
|
||||
var tx = eth.transact(data.args[0], data.args[1], data.args[2],data.args[3],data.args[4],data.args[5])
|
||||
postData(data._seed, tx)
|
||||
var tx = eth.transact(data.args[0], data.args[1], data.args[2],data.args[3],data.args[4],data.args[5])
|
||||
postData(data._seed, tx)
|
||||
|
||||
break
|
||||
case "create":
|
||||
postData(data._seed, null)
|
||||
break
|
||||
|
||||
break
|
||||
case "getStorage":
|
||||
require(2);
|
||||
require(2);
|
||||
|
||||
var stateObject = eth.getStateObject(data.args[0])
|
||||
var storage = stateObject.getStorage(data.args[1])
|
||||
postData(data._seed, storage)
|
||||
var stateObject = eth.getStateObject(data.args[0])
|
||||
var storage = stateObject.getStorage(data.args[1])
|
||||
postData(data._seed, storage)
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
case "getStateKeyVals":
|
||||
require(1);
|
||||
var stateObject = eth.getStateObject(data.args[0]).stateKeyVal(true)
|
||||
postData(data._seed,stateObject)
|
||||
require(1);
|
||||
var stateObject = eth.getStateObject(data.args[0]).stateKeyVal(true)
|
||||
postData(data._seed,stateObject)
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
case "getTransactionsFor":
|
||||
require(1);
|
||||
var txs = eth.getTransactionsFor(data.args[0], true)
|
||||
postData(data._seed, txs)
|
||||
require(1);
|
||||
var txs = eth.getTransactionsFor(data.args[0], true)
|
||||
postData(data._seed, txs)
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
case "getBalance":
|
||||
require(1);
|
||||
require(1);
|
||||
|
||||
postData(data._seed, eth.getStateObject(data.args[0]).value());
|
||||
postData(data._seed, eth.getStateObject(data.args[0]).value());
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
case "getKey":
|
||||
var key = eth.getKey().privateKey;
|
||||
var key = eth.getKey().privateKey;
|
||||
|
||||
postData(data._seed, key)
|
||||
break
|
||||
|
||||
postData(data._seed, key)
|
||||
break
|
||||
case "watch":
|
||||
require(1)
|
||||
eth.watch(data.args[0], data.args[1]);
|
||||
break
|
||||
require(1)
|
||||
eth.watch(data.args[0], data.args[1]);
|
||||
|
||||
break
|
||||
|
||||
case "disconnect":
|
||||
require(1)
|
||||
postData(data._seed, null)
|
||||
break;
|
||||
case "set":
|
||||
console.log("'Set' has been depcrecated")
|
||||
/*
|
||||
for(var key in data.args) {
|
||||
if(webview.hasOwnProperty(key)) {
|
||||
window[key] = data.args[key];
|
||||
}
|
||||
}
|
||||
*/
|
||||
break;
|
||||
require(1)
|
||||
postData(data._seed, null)
|
||||
|
||||
break;
|
||||
|
||||
case "getSecretToAddress":
|
||||
require(1)
|
||||
postData(data._seed, eth.secretToAddress(data.args[0]))
|
||||
break;
|
||||
require(1)
|
||||
postData(data._seed, eth.secretToAddress(data.args[0]))
|
||||
|
||||
break;
|
||||
|
||||
case "debug":
|
||||
console.log(data.args[0]);
|
||||
console.log(data.args[0]);
|
||||
break;
|
||||
}
|
||||
} catch(e) {
|
||||
|
@ -215,12 +235,13 @@ ApplicationWindow {
|
|||
postEvent(ev, [storageObject.address, storageObject.value])
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: toggleInspector
|
||||
color: "#bcbcbc"
|
||||
visible: true
|
||||
height: 12
|
||||
width: 12
|
||||
height: 20
|
||||
width: 20
|
||||
anchors {
|
||||
right: root.right
|
||||
}
|
||||
|
@ -233,8 +254,8 @@ ApplicationWindow {
|
|||
inspector.url = webview.experimental.remoteInspectorUrl
|
||||
}
|
||||
}
|
||||
|
||||
onDoubleClicked: {
|
||||
console.log('refreshing')
|
||||
webView.reload()
|
||||
}
|
||||
anchors.fill: parent
|
||||
|
|
|
@ -282,7 +282,11 @@ func (gui *Gui) insertTransaction(window string, tx *ethchain.Transaction) {
|
|||
ptx.Sender = s
|
||||
ptx.Address = r
|
||||
|
||||
gui.getObjectByName("transactionView").Call("addTx", window, ptx, inout)
|
||||
if window == "post" {
|
||||
gui.getObjectByName("transactionView").Call("addTx", ptx, inout)
|
||||
} else {
|
||||
gui.getObjectByName("pendingTxView").Call("addTx", ptx, inout)
|
||||
}
|
||||
}
|
||||
|
||||
func (gui *Gui) readPreviousTransactions() {
|
||||
|
|
|
@ -17,6 +17,9 @@ const (
|
|||
func main() {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
||||
// This is a bit of a cheat, but ey!
|
||||
os.Setenv("QTWEBKIT_INSPECTOR_SERVER", "127.0.0.1:99999")
|
||||
|
||||
qml.Init(nil)
|
||||
|
||||
var interrupted = false
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/ethereum/eth-go"
|
||||
|
@ -42,6 +43,15 @@ func (self *UiLib) EvalJavascriptFile(path string) {
|
|||
self.jsEngine.LoadExtFile(path[7:])
|
||||
}
|
||||
|
||||
func (self *UiLib) EvalJavascriptString(str string) string {
|
||||
value, err := self.jsEngine.Run(str)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v", value)
|
||||
}
|
||||
|
||||
func (ui *UiLib) OpenQml(path string) {
|
||||
container := NewQmlApplication(path[7:], ui)
|
||||
app := NewExtApplication(container, ui)
|
||||
|
|
Loading…
Reference in New Issue