星期三, 十二月 02, 2015

pyqt 5定制数据模型/Custom data model

目的:qml中combobox的Model用python实现 Model,并通过QML显示出来
要点:qt 5已经改变了roleNames方法,字符串需要用原始ascll 码,字符串前面加b来实现改点;
数据项目必须扩展来自pyqt 5的object.

ListModel.py
from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QAbstractListModel, QModelIndex, Qt, QUrl, QVariant
                   
class LottoListModel(QtCore.QAbstractListModel):
    titleRole = Qt.UserRole + 1
    def __init__(self, parent=None):
        super(LottoListModel, self).__init__(parent)

        self.items = []
    def roleNames(self):
        names = {}
        names[self.titleRole] = b"title"
       # names[self.colorRole] = "color"
        return names
         
    def appendRow(self, item):
        self.items.append(item)

    def rowCount(self, parent=QtCore.QModelIndex()):
        print('rowcount.....')
        return len(self.items)

    def data(self, index, role=Qt.DisplayRole):
        print('get data....',index,'   ',role)
        try:
            item = self.items[index.row()]
        except IndexError:
            return QVariant()

        if role == self.titleRole:
            return item.title()


        return QVariant()         

class LottoListItem(object):#核心关键,必须是python object的子类作为项目
    def __init__(self, title):
        self._title = title


    def title(self):
        return self._title

main.py:
import sys
import os
from PyQt5.QtCore import QObject, QUrl, pyqtSlot, QVariant
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import QObject, QUrl, Qt,QAbstractTableModel
from PyQt5.QtCore import  pyqtProperty,pyqtSignal
import PyQt5
import ListModel as LM
class MainApp(QObject):
     @pyqtSlot(result=QVariant)
     def getAlgorithm(self):
          self.myModel=LM.LottoListModel()
          self.myModel.appendRow(LM.LottoListItem("0001"))    
          self.myModel.appendRow(LM.LottoListItem("0002"))         
          return self.myModel;

app = QGuiApplication (sys.argv)
engine=QQmlApplicationEngine()
ctx = engine.rootContext()

engine.load(QUrl("view.qml "))
window = engine.rootObjects()[0]
_MainApp = MainApp(window)
_MainApp.logwin[str].connect(window.logger)
_MainApp.getAlgorithm();
ctx.setContextProperty("py_MainApp", _MainApp)

window.show()
sys.exit(app.exec_())

         
view.qml

import QtQuick 2.5
import QtQuick.Controls 1.4
Rectangle {
   id: myItem

     color:'red'
   width: 500; height: 500


ComboBox {
    model:py_MainApp.getAlgorithm()
    width: 200
     }
ListView {
    width: 200; height: 250

    model: myModel
    delegate: Text {title }
     }
}

星期六, 十一月 07, 2015

pyqt5 可以把Python和QT5都可以关联起来。

今天把QT5下的一个QML程序简单移植到python下,通过pyqt5,果然非常的强大。
pyqt5非常强大

星期三, 五月 27, 2015

ofbiz 用于netbeans/Eclipse 定制。

1.NetBean 8.0.2/jdk .1.8/ofbiz 13.07.02
关键一点:新建项目使用Netbeans的 Java /Java Free-Form Project,Java自由格式项目
到Ofbiz展开的目录即可。非常简单。
编译是只需要找到build.xml选择里面的各种人物,运行执行即可。

2.Eclipse4.4/jdk 1.8/ofbiz 13.07.02

https://cwiki.apache.org/confluence/display/OFBIZ/Eclipse+Tips
 
 现在的ofbiz .zip包里就应该包含了Eclipse .project文件,所以打开Ofbiz是更加容易的。
不过需要注意的是Eclipse的work space不能直接在ofbiz的展开目录上比如:
D:\apache-ofbiz-13.07.02 上打开;
打开ofbiz在Eclipse只要选择Import然后选择"Existing Project into Workspace",然后
在目录里输入:D:\apache-ofbiz-13.07.02,选择结束即可。
调试什么的参考:
https://cwiki.apache.org/confluence/display/OFBIZ/Running+and+Debugging+OFBiz+in+Eclipse

星期二, 五月 26, 2015

成功在jdk.1.8.0_45 x64/MariaDB 10.0.19_x64/安装成功ofbiz-13.07.02

ofbiz-13.07.01,有个问题,在jdk 1.8的时候,安装完demo.ant load-demo后
浏览http://127.0.0.0:8080/ecommerce的时候,页面语言菜单无法显示,出现异常。
只能降级到 jdk 1.7使用。
这个新的版本  13.07.02 这个bug修复了。并且成功在MariaDB上也就是Mysql 5.6上
安装成功!!!!!!!

漂亮。

星期五, 五月 08, 2015

QT 5.4 天龙八部 中高级提高

1The Meta-Object System
 QT核心基础概念
http://doc.qt.io/qt-5/metaobjects.html#meta-object-system
2Models and Views in Qt Quick
综合应用预览篇。
http://doc.qt.io/qt-5/qtquick-modelviewsdata-modelview.html
3Model/View Programming
QT 核心综合概念
http://doc.qt.io/qt-5/model-view-programming.html
4Using C++ Models with Qt Quick Views
综合快速引用QML/C++ 
http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html
5Writing QML Extensions with C++
 理解深入隐藏在后面的概念
http://doc.qt.io/qt-5/qtqml-tutorials-extending-qml-example.html
6Integrating QML and C++http://doc.qt.io/qt-5/qtqml-cppintegration-topic.html
7Exposing Attributes of C++ Types to QML http://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html
8Defining QML Types from C++http://doc.qt.io/qt-5/qtqml-cppintegration-definetypes.html
9


 

星期四, 四月 02, 2015

QT 5 i18n sample(or example ) step by step

1.新建一个目录 
  cd c:\temp;mkdir testi18n
cd testi18n

2.新建最简单cpp
 i18n.cpp
#include <QApplication>
#include <QLabel>
#include <QTranslator>
#include <QDebug>
int main(int argc,char *argv[])
{
QApplication app(argc,argv);

    // translation file for application strings
    QTranslator translator;
   bool result= translator.load("superapp_zh_CN",":/i18n"); //这里的:/i18n 可以参考后面的 i18n.qrc 中的prefix中的对应关系
   qDebug()<<"load resource flag:"<<result;
               app.installTranslator(&translator);
                 qDebug()<<QLocale::system().name();
QLabel * label = new QLabel(QObject::tr("Hello"));//应该根据语言切换
           qDebug()<<QObject::tr("Hello"); //应该根据语言切换
label->show();
app.exec();
}
3.创建项目文件
 qmake -project //建立testi18n.pro文件
4.编辑项目文件,加入i18n 字典说明
    在testi18n.pro中加入英文和中文两个数据字典文件:
TRANSLATIONS    = superapp_en_US.ts \
                     superapp_zh_CN.ts 
5.创建资源文件
 lupdate testi18n.pro //第3步建立
  C:\temp\qt\testi18n>lupdate testi18n.pro
Updating 'superapp_en_US.ts'...
    Found 1 source text(s) (0 new and 1 already existing)
Updating 'superapp_zh_CN.ts'...
    Found 1 source text(s) (0 new and 1 already existing)

6.使用linguist来编辑翻译字典
    注意打开打开翻译翻译必须确认,也就是蓝色的对号,然后保存,如果不保存,最后生成字典二进制资源文件的时候,将不会被编译,
    直接打开.ts文件可以看到,没有点对号确认的字典项目对应 一个type="unfinished",只有确认了之后,才变成标准的
<translation type="unfinished">你好世界</translation>
 linguist里 确认后变成:
        <translation>你好世界</translation>
7.编译生成二进制字典文件
 lrelease testi18n.pro
C:\temp\qt\testi18n>lrelease testi18n.pro
Updating 'C:/temp/qt/testi18n/superapp_en_US.qm'...
    Generated 1 translation(s) (1 finished and 0 unfinished)
Updating 'C:/temp/qt/testi18n/superapp_zh_CN.qm'...
    Generated 1 translation(s) (1 finished and 0 unfinished)

8.建立资源文件i18n.qrc
  <RCC>
<qresource prefix="/i18n" > //注意prefix 是用来标明在最终二进制文件中资源文件的引用目录,可以是唯一的任意字符串
<file>superapp_en_US.qm</file>
<file>superapp_zh_CN.qm</file>
</qresource>
</RCC>
9.将资源文件加入项目文件testi18n.pro中
RESOURCES +=i18n.qrc

10.生成Makefile文件
   qmake testi18n.pro

11.编译生成.exe文件
   make

12.运行
 release\testi18n.exe


星期四, 三月 05, 2015

javafx Scene Builder 2.0 如何给anchorpane加入一个本地背景图像

通过Css来加入:
-fx-background-image:url("file:///C:/nyayanew/config/game3/bgl1f2.jpg")
类似代码:
File f = new File("C:\\nyayanew\\config\\game3\\bgl1f2.jpg");
center.setStyle("-fx-background-image:file:///" + f.getAbsolutePath().replace("\\", "/"));

星期五, 一月 23, 2015

如何在JavaFx 8里实现 Hover效果。

css 3 transform:
 .myimage:hover {
  background-color: #dae7f3;
  transform: translate(-5px,-5px);
  effect: dropshadow( three-pass-box , rgba(0,0,0,1) , 5, 0.0 , 0 , 1 );
  box-shadow: 5px 5px 15px rgba(67, 72, 84, 0.5);
}

但是javafx 8只支持css 2.1 和部分css 3的语法,恰恰transform不在此列:
不过可以通过-fx-translate-x,和draopshadow实现悬浮图片或者其他物体的效果.
在css文件中定义一下class selector,然后在JavaFX Scene Builder 2.0 设置 style class 为myButton即可.
.myButton:hover {
  -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,1) , 5, 0.0 , 0 , 1 );
   -fx-translate-x: -5px;
   -fx-translate-y: -5px;
}

星期三, 一月 21, 2015

how ant task read manifest.mf from another jar file.

经常需要在打包可执行jar包的时候,将众多jar打包成一个jar包,
但是只有一个主项目的MANIFEST.MF是需要的。其他的jar包的
MANIFEST.MF都可以忽略掉。
其实很简单的方法:
        <zip destfile="final.jar">
            <zipfileset src="store/temp_final.jar"
            excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA,META-INF/MANIFEST.MF"/>
这里将其他jar包的MANIFEST.MF给去掉了。
            <zipfileset src="dist/project.jar" includes="META-INF/**"/>           
这里将project.jar里的MENIFEST.MF放到最终的jar包里
        </zip>
zipfieset 的prefix属性是用来指明最终jar包里的目录结构,这提供了更加灵活的方式。
不过这里不需要通过prefix来指明最终的jar包目录结构,如果是通过引入一个文件作为MANIFEST.MF,prefix属性就是经常需要的了。
不过一个文件就是使用<fileset >任务来引入了。


星期四, 一月 01, 2015

curl link static under windows x64 error:undefined reference to WSAIoctl@36

依然是少了link 库的原因。
加入一下库即可连接成静态库,避免错误
:
libwldap32.a libws2_32.a libwsock32.a \libmswsock.a

星期二, 十二月 30, 2014

Nginx+jboss session问题。

用Nginx做反向代理,Jboss做动态内容处理,或者也是集群,
就必然涉及到session的问题。
这个方法简单的,可以在Nginx设置, upstream的算法,为ip_hash,
同一个客户使用固定的jboss服务器。
另外一个就是使用jboss 实现session replication(session复制).
可以查阅手册解决之。

星期日, 十月 12, 2014

星期一, 九月 22, 2014

如何动态载入外部储存卡上的dex/jar包?

java的概念定制ClassLoader非常强大,Android提供了两个classloader来完成相关的任务.
PathClassLoader: 只能读取已经保存在系统里的jar/dex包
DexClassLoader:可以灵活读取任何权限允许的jar包。
我们设想可以读取保存在外部存储卡上的jar,更加符合实际的逻辑需要:
设计:
将动态jar包保存在/sdcard/temp/testjar.jar 文件里,在app里调用载入该包,并执行特定的方法:

1.Android Activtiy 准备动态载入相关代码:
将该方法加入到app某个菜单项目
onOptionsItemSelected方法里来调用,该app package为home.sunose假设:

public String classLoadFromExtern(Activity acivity)
{
 String result="";
 String sdcard=Environment.getExternalStorageDirectory().getAbsolutePath();
 String jarPath = sdcard
             + "/temp/testjar.jar";
String tmppath=acivity.getDir( "temp", 0).getAbsolutePath();
//注意tmppath是用来将testjar.jar展开的目录,这个目录必须属于当前app的用户id,所以必须使用
//context上下文相关的getDir得到该目录,避免没有权限的错误:
//DexClassLoader is not owned by the current user 这个异常.
//这是private DexFile(String sourceName, String outputName, int flags) throws IOException 
//的判断Libcore.os.getuid() != Libcore.os.stat(parent).st_uid

Log.d (TAG ,tmppath );
 DexClassLoader myClassLoader = new DexClassLoader (jarPath ,tmppath ,null, ClassLoader.getSystemClassLoader());
    try
     {
         Class<?>  clazz = myClassLoader .loadClass("com.test.First");
//         AIObject aio=(AIObject)clazz.newInstance();
         Method method = clazz.getDeclaredMethod("execute" ,String.class);
         method.setAccessible(true);
          result=(String)method .invoke(clazz.newInstance(), "test");
     }
     catch(Exception ex)
     {
         ex.printStackTrace();
     }
 return result;
}

2.准备桌面com.test.First.java类:
package com.test;
public class First
{
public String execute(String term)
{
String result=new java.util.Date()+" term is "+term;  
System.out.println(result);
return result;
}
}
5.mkdir com;mkdir com\test //建立标准java package目录结构,准备
6.cd c:\temp\com\test ,建立First.java,内容为步骤2内容

7.javac  com\test\First.java -d classes //编译java文件,并将编译后的class输出到c:\temp\classes目录

//准备dex打包编译的class
8.D:\Android\android-sdk-windows\build-tools\20.0.0\dx.bat  --dex --output c:\temp\testjar.jar  c:\temp\classes
9.adb push testjar.jar /sdcard/temp/  //推送到android上
10.在app中调用步骤1的方法后,adb logcat 可以看到
后台Logcat的输出:
D/dalvikvm(31581): DexOpt: --- BEGIN 'testjar.jar' (bootstrap=0) ---
D/dalvikvm(31608): DexOpt: load 5ms, verify+opt 1ms, 93356 bytes
D/dalvikvm(31581): DexOpt: --- END 'testjar.jar' (success) ---
D/dalvikvm(31581): DEX prep '/storage/emulated/0/temp/testjar.jar': unzip in 0ms, rewrite 98ms

11.也可以看到testjar.jar 实际展开后的目录:
 adb shell
ls /data/data/home.sunose/app_temp

星期一, 九月 08, 2014

嵌入在ScrollView里的GridView如何动态修改Layout 宽度? GridView In ScrollView programmatically change layout size ?

其实宽度修改都很简答。
以下伪代码:
GridView gv = this.findViewById(R.id.gridview_id);
               gv.getLayoutParams(). width = 1965;//px width
              gv.getLayoutParams(). height = LayoutParams. WRAP_CONTENT;
然后根据需要调用这个UI 刷新即可,一下两行代码可有可无. 
                   View vg =   getWindow().getDecorView().getRootView();
                   vg.invalidate();   
但是如果想给GridView加上水平滚动条则问题就有些麻烦了.需要将GridView嵌入在ScrollView或者HorizontalScrollView

<HorizontalScrollView>
 <GridView></GridView>
</HorizontalScrollView>

此时在代码中修改LayoutParams.width的方法,发现对GridView突然不起作用了.这个时候一个奇怪的技巧就起作用了.
将GridView再包围一个Layout即可。
修改为:
<HorizontalScrollView>
      <LinearLayout  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:orientation="vertical" >
 <GridView></GridView>
</LinearLayout>
</HorizontalScrollView>
这个技巧花费了数天才无意中发现。

星期二, 九月 02, 2014

Android 各种目录的获取。

Android 在内部rom里的存储路径和外部存储卡上的存储目录,可以通过
调用Activity的函数来获取。
Activity.getFilesDir().getAbsolutePath()得到:
   /data/data/<App Package name>/files
Activity.getExternalFilesDir(null).getAbsolutePath()得到:
/storage/emulated/0/Android/data/
<App Package name>/files
Environment.getExternalStorageDirectory().getAbsolutePath()
得到:
/storage/emulated/0

/storage/emulated/0是外部储存卡mount到系统的路劲入口,可以通过检测状态来确认是否有外部存储卡。
读取外部存储卡要在Androidmanifest.xml里加入权限:
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

星期日, 八月 31, 2014

GIMP 2.8不能编辑GIF和png图片问题

GIF和png颜色空间都是indexed,所以无法编辑。

如果想编辑必须首先转换颜色空间,这个非常容易,只要在image/颜色菜单里
选择mode(模式)即可转换



​

星期三, 八月 27, 2014

如何在Android里使用最新的Apache Httpclient

注意:Android最早使用的Apache HttpClient 4.0-beta的一个包,后来基本
不再维护,所以如果有更多的新的HTTP 特性,基本不再支持,
而且,Android推荐大家使用系统标准的java标准包:HttpURLConnection 
但是HttpURLConnection比较底层,使用起来非常的不便,尤其是在
    类似提交Form和服务器传送数据的时候;所以最近有okHttp就封装了HttpURLConnction
给开发人员提供了较好的API.但是使用起来依然不如HttpRequest爽快.
尤其是在目前稍微严肃的应用都会基于HTTPS/SSL的基础之上,大量的验证
模式支持就是以前的4.0版本不支持的。没有现成的方案。所以使用
  最新的httpclient包是必须的了。
但是由于httpclient是基于标准JDK的,有许多牵涉到版权的API比如
misc.sun之类的包不能在Android上使用,所以这个处理工作还是比较繁琐的。
幸运的是apache提供了Android移植包:
参考,写本文时的最新版本4.3.5:
http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html
  
可以在www.mvnrepository.com上 输入httpclient-android来寻找最新的
jar包Android移植版本并下载即可。
当然有些类不可避免的原始的类的功能不同并有扩展,这个时候,就要使用
类名带HC4结尾的类来使用最新的功能特性了
 
但是如果我们在Android Activity调用Async或者Thread调用最基本的:
CloseableHttpClient httpclient = HttpClients.createDefault();
立即出现异常:
 java.lang.IllegalArgumentException: Item may not be null
  
查看代码则是:
  org.apache.http.config.RegistryBuilder.java
的  Args.notNull(item, "Item");造成了错误。
阅读代码发现,这是因为SocketFactory为空造成的,所以
必须首先初始化,SocketFactory

 SSLContext sslContext = SSLContexts.createSystemDefault();
   SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
         sslContext,
         SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);
 CloseableHttpClient  httpclient= HttpClientBuilder.create()
      .setSSLSocketFactory(sslsf)
      .build();

或者使用定制的方法:

 ConnectionSocketFactory plainsf = <...>  LayeredConnectionSocketFactory sslsf = <...>  Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory>create()          .register("http", plainsf)          .register("https", sslsf)          .build();    HttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(r);  HttpClients.custom()          .setConnectionManager(cm)          .build();

这个都可以从hc.apache.org对应版本的tutorial章节,看到详细的代码

注意在android使用需要在AndroidManifest.xml里加入权限:
<uses-permission android:name="android.permission.INTERNET"/>
  这个httpclient-android-4.3.5.jar在Android Studio和Eclipse ADT
里如何打包到最后的apk里步骤不同,使用的时候注意即可。

星期四, 八月 21, 2014

Button 实现淡入淡出动画

布局文件:
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.buttonana.MainActivity" >
  <Button
      android:layout_marginTop="50dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"     
      android:id="@+id/animationid"
      android:text="fade out"/>

  <Button
      android:id="@+id/mainbtn"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_alignLeft="@+id/animationid"
      android:layout_alignParentTop="true"
      android:layout_marginTop="170dp"
      android:text="Click Me" />

</RelativeLayout>

关键语句:
      amt.setFillAfter(true);//important.

package com.example.buttonana;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;

public class MainActivity extends Activity {

    Button mainbtn;
    Button animationbtn;
   
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainbtn=(Button)this.findViewById(R.id.mainbtn);
        animationbtn=(Button)this.findViewById(R.id.animationid);
        mainbtn.setOnClickListener(new View.OnClickListener() {
           
            @Override
            public void onClick(View v) {
                Log.d("BUTTON","enter.........................................................");
                Animation t =getAnimation();
                animationbtn.clearAnimation();
                animationbtn.setAnimation(t);
                t.startNow();
            }
        });
       
    }
  public Animation getAnimation()
  {
      Animation amt=new AlphaAnimation(1.0f,0.01f);
      amt.setDuration(4*1000);
      amt.setFillAfter(true);//important.
      return amt;
     
  }

}

星期二, 八月 05, 2014

gradle 调用另外一个gradle 脚本文件

gradle 0.9 之后,支持apply from: "addiontal.gradle"语法。

星期日, 八月 03, 2014

Android Studio Beta 打包源代码和build.gradle 脚本到一个zip文件

在build.gradle脚本里加入脚本:

task srcZip2(type: Zip) {
    classifier = 'src'
    from projectDir
    include 'src/**/*'
    include 'build.gradle'
    destinationDir file('.')
    archiveName "src.zip"
}


tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
        task.dependsOn 'srcZip2'
    }
}


最后就在当前 app目录下建立了src.zip文件。