.. index:: single: デスクトップとモバイル開発 (RingQt); はじめに =================================== デスクトップとモバイル開発 (RingQt) =================================== Ring アプリケーション (デスクトップとモバイル) 開発のために Qt フレームワーククラスの用法を学びます。 .. index:: pair: RingQt によるデスクトップとモバイル開発; はじめての GUI アプリケーション はじめての GUI アプリケーション =============================== この用例では、彼氏、彼女の名前を質問するアプリケーションを作成します。 ユーザがテキストボックスへ名前を入力して “Say Hello” ボタンをクリックした後に、 “Hello ” を名前へ追加することでテキストボックスの値を更新します。 .. code-block:: ring Load "guilib.ring" oApp = New qApp { win1 = new qWidget() { setwindowtitle("Hello World") setGeometry(100,100,370,250) label1 = new qLabel(win1) { settext("What is your name ?") setGeometry(10,20,350,30) setalignment(Qt_AlignHCenter) } btn1 = new qpushbutton(win1) { setGeometry(10,200,100,30) settext("Say Hello") setclickevent("pHello()") } btn1 = new qpushbutton(win1) { setGeometry(150,200,100,30) settext("Close") setclickevent("pClose()") } lineedit1 = new qlineedit(win1) { setGeometry(10,100,350,30) } show() } exec() } Func pHello lineedit1.settext( "Hello " + lineedit1.text()) Func pClose oApp.quit() プログラムの実行結果: 最初にテキストボックスへ名前を入力します。 .. image:: ringqt_shot1.jpg :alt: テキストボックスへの名前入力 そして Say Hello ボタンをクリックします。 .. image:: ringqt_shot2.jpg :alt: ボタンのクリック .. index:: pair: デスクトップとモバイル開発 (RingQt); イベントループ イベントループ ============== qApp クラスから exec() メソッドを呼び出すときは Qt はイベント駆動とイベントループで制御します。 一度でも exec() を呼び出すと、イベントループを開始し、ウィジェットは様々なイベントへの応答を開始します (マウス、キーボード、タイマーなど)。 イベントが発行されてコールバック関数が呼び出されるときは再び制御を戻します。 コールバック関数の実行完了後、制御をイベントループへ再び戻します。 覚えていると便利なことは (1) ほとんどの作業は標準イベントで行います (イベントは各種ウィジェットで用意されています)。 (2) イベントフィルタを使うとウィジェットにイベントを追加できます。 (3) タイマーを使うと制御を戻します。これにより、各種検査を簡単にできます。 コールバック関数で処理時間がかかり、ビジー状態であるとき、 GUI の停止を回避するために qApp クラスで ProcessEvents() メソッドを呼び出せます。 .. code-block:: ring oApp.processevents() exec() メソッドを呼び出さずに、メインループを作成することもできます。 この方法は非推奨であり、選択肢の一つに過ぎません。 .. code-block:: ring # exec() メソッドを呼び出さない方法 while true oApp.processevents() # GUI イベントへの応答 # さらにコードを追加することで、制御を行います! # ..... end .. index:: pair: RingQt によるデスクトップとモバイル開発; レイアウトの用法 レイアウトの用法 ==================== この用例は、前述のアプリケーションで垂直レイアウトを使用するように更新したものです。 .. code-block:: ring Load "guilib.ring" MyApp = New qApp { win1 = new qWidget() { setwindowtitle("Hello World") setGeometry(100,100,400,130) label1 = new qLabel(win1) { settext("What is your name ?") setGeometry(10,20,350,30) setalignment(Qt_AlignHCenter) } btn1 = new qpushbutton(win1) { setGeometry(10,200,100,30) settext("Say Hello") setclickevent("pHello()") } btn2 = new qpushbutton(win1) { setGeometry(150,200,100,30) settext("Close") setclickevent("pClose()") } lineedit1 = new qlineedit(win1) { setGeometry(10,100,350,30) } layout1 = new qVBoxLayout() { addwidget(label1) addwidget(lineedit1) addwidget(btn1) addwidget(btn2) } win1.setlayout(layout1) show() } exec() } Func pHello lineedit1.settext( "Hello " + lineedit1.text()) Func pClose MyApp.quit() 実行中のアプリケーション! .. image:: ringqt_shot3.jpg :alt: 垂直レイアウト .. index:: pair: RingQt によるデスクトップとモバイル開発; QTextEdit クラスの用法 QTextEdit クラスの用法 ========================== この用例では、 QTextEdit クラスを使用しています。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qWidget() { setwindowtitle("QTextEdit Class") setGeometry(100,100,500,500) new qtextedit(win1) { setGeometry(10,10,480,480) } show() } exec() } 実行中は qtextedit へリッチテキストを貼り付けることができます。 .. image:: ringqt_shot4.jpg :alt: QTextEdit クラス .. index:: pair: RingQt によるデスクトップとモバイル開発; QListWidget クラスの用法 QListWidget クラスの用法 ============================ この用例では、 QListWidget クラスを使用しています。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qWidget() { setGeometry(100,100,400,400) list1 = new qlistwidget(win1) { setGeometry(150,100,200,200) alist = ["one","two","three","four","five"] for x in alist additem(x) next setcurrentrow(3,2) win1.setwindowtitle("Items Count : " + count() ) } btn1 = new qpushbutton(win1) { setGeometry(10,200,100,30) settext("selected item") setclickevent("pWork()") } btn2 = new qpushbutton(win1) { setGeometry(10,240,100,30) settext("Delete item") setclickevent("pWork2()") } show() } exec() } func pWork btn1.settext(string(list1.currentrow())) func pWork2 list1 { takeitem(currentrow()) } 実行中のアプリケーション .. image:: ringqt_shot5.jpg :alt: QListWidget Class 別の用例: .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qWidget() { setGeometry(100,100,500,400) list1 = new qlistwidget(win1) { setGeometry(150,100,200,200) alist = ["one","two","three","four","five"] for x in alist additem(x) next setcurrentrow(3,2) win1.setwindowtitle("Items Count : " + count() ) } btn1 = new qpushbutton(win1) { setGeometry(10,200,100,30) settext("selected item") setclickevent("pWork()") } btn2 = new qpushbutton(win1) { setGeometry(10,240,100,30) settext("Delete item") setclickevent("pWork2()") } show() } exec() } func pWork nbrOfItems = list1.count() curItemNbr = list1.currentrow() curValue = list1.item(list1.currentrow()).text() win1.setwindowtitle( "After Select - NbrOfItems: " + nbrOfItems + " CurItemNbr: " + curItemNbr + " CurValue: " + curValue ) btn1.settext( string(list1.currentrow() ) + " --- " + list1.item(list1.currentrow()).text() ) func pWork2 list1 { takeitem(currentrow()) nbrOfItems = count() curItemNbr = currentrow() curValue = item(currentrow()).text() win1.setwindowtitle("After Delete - NbrOfItems: " + nbrOfItems + " CurItemNbr: " + curItemNbr +" CurValue: " + curValue ) } .. index:: pair: RingQt によるデスクトップとモバイル開発; QTreeView および QFileSystemModel の用法 QTreeView および QFileSystemModel の用法 ============================================ この用例では、ファイルシステムを表示するために QTreeView ウィジェットの用法を学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = New qWidget() { setwindowtitle("Using QTreeView and QFileSystemModel") setGeometry(100,100,500,400) New qtreeview(win1) { setGeometry(00,00,500,400) oDir = new QDir() ofile = new QFileSystemModel() ofile.setrootpath(oDir.currentpath()) setmodel(ofile) } show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot6.jpg :alt: QTreeView および QFileSystemModel .. index:: pair: RingQt によるデスクトップとモバイル開発; QTreeWidget と QTreeWidgetItem の用法 QTreeWidget と QTreeWidgetItem の用法 ========================================= この用例では、 QTreeWidget および QTreeWidgetItem クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qWidget() { setwindowtitle("TreeWidget") setGeometry(100,100,400,400) layout1 = new qvboxlayout() tree1 = new qtreewidget(win1) { setGeometry(00,00,400,400) setcolumncount(1) myitem = new qtreewidgetitem() myitem.settext(0,"The First Step") addtoplevelitem(myitem) for x = 1 to 10 myitem2 = new qtreewidgetitem() myitem2.settext(0,"hello"+x) myitem.addchild(myitem2) for y = 1 to 10 myitem3 = new qtreewidgetitem() myitem3.settext(0,"hello"+x) myitem2.addchild(myitem3) next next setheaderlabel("Steps Tree") } layout1.addwidget(tree1) setlayout(layout1) show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot7.jpg :alt: QTreeWidget と QTreeWidgetItem .. index:: pair: RingQt によるデスクトップとモバイル開発; QComboBox クラスの用法 QComboBox クラスの用法 ========================== この用例では、 QComboBox クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qWidget() { setwindowtitle("Using QComboBox") setGeometry(100,100,400,400) New QComboBox(win1) { setGeometry(150,100,200,30) alist = ["one","two","three","four","five"] for x in aList additem(x,0) next } show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot8.jpg :alt: QComboBox .. index:: pair: RingQt によるデスクトップとモバイル開発; メニューバーの作成方法 メニューバーの作成方法 ====================== この用例では、 QMenuBar クラスを学びます。 .. code-block:: ring Load "guilib.ring" MyApp = New qApp { win1 = new qWidget() { setwindowtitle("Using QMenubar") setGeometry(100,100,400,400) menu1 = new qmenubar(win1) { sub1 = addmenu("File") sub2 = addmenu("Edit") sub3 = addmenu("Help") sub1 { oAction = new qAction(win1) { settext("New") } addaction(oAction) oAction = new qAction(win1) { settext("Open") } addaction(oAction) oAction = new qAction(win1) { settext("Save") } addaction(oAction) oAction = new qAction(win1) { settext("Save As") } addaction(oAction) addseparator() oAction = new qaction(win1) { settext("Exit") setclickevent("myapp.quit()") } addaction(oAction) } sub2 { oAction = new qAction(win1) { settext("Cut") } addaction(oAction) oAction = new qAction(win1) { settext("Copy") } addaction(oAction) oAction = new qAction(win1) { settext("Paste") } addaction(oAction) addseparator() oAction = new qAction(win1) { settext("Select All") } addaction(oAction) } sub3 { oAction = new qAction(win1) { settext("Reference") } addaction(oAction) sub4 = addmenu("Sub Menu") sub4 { oAction = new qAction(win1) { settext("Website") } addaction(oAction) oAction = new qAction(win1) { settext("Forum") } addaction(oAction) oAction = new qAction(win1) { settext("Blog") } addaction(oAction) } addseparator() oAction = new qAction(win1) { settext("About") } addaction(oAction) } } show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot9.jpg :alt: QMenuBar .. index:: pair: RingQt によるデスクトップとモバイル開発; コンテキストメニュー コンテキストメニュー ==================== 用例: .. code-block:: ring load "guilib.ring" new qApp { win = new qwidget() { setwindowtitle("Context Menu") resize(400,400) myfilter = new qAllEvents(win) { setContextmenuEvent("mymenu()") } installeventfilter(myfilter) show() } exec() } func mymenu new qMenu(win) { oAction = new qAction(win) { settext("new") SetCLickevent("See :New") } addaction(oAction) oAction = new qAction(win) { settext("open") SetCLickevent("See :Open") } addaction(oAction) oAction = new qAction(win) { settext("save") SetCLickevent("See :Save") } addaction(oAction) oAction = new qAction(win) { settext("close") SetCLickevent("See :Close") } addaction(oAction) oCursor = new qCursor() exec(oCursor.pos()) } .. index:: pair: RingQt によるデスクトップとモバイル開発; ツールバーの作成方法 ツールバーの作成方法 ==================== この用例では、 QToolBar クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("Using QToolbar") setGeometry(100,100,600,400) abtns = [ new qpushbutton(win1) { settext("Add") } , new qpushbutton(win1) { settext("Edit") } , new qpushbutton(win1) { settext("Find") } , new qpushbutton(win1) { settext("Delete") } , new qpushbutton(win1) { settext("Exit") setclickevent("win1.close()") } ] tool1 = new qtoolbar(win1) { for x in abtns addwidget(x) addseparator() next setmovable(true) setGeometry(0,0,500,30) setFloatable(true) } show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot10.jpg :alt: QToolBar .. index:: pair: RingQt によるデスクトップとモバイル開発; ステータスバーの作成方法 ステータスバーの作成方法 ======================== この用例では、 QStatusBar クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("Using QStatusbar") setGeometry(100,100,400,400) status1 = new qstatusbar(win1) { showmessage("Ready!",0) } setstatusbar(status1) show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot11.jpg :alt: QStatusBar .. index:: pair: RingQt によるデスクトップとモバイル開発; QDockWidget の用法 QDockWidget の用法 ====================== この用例では、 QDockWidget クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("QDockWidget") setGeometry(100,100,400,400) label1 = new qlabel(win1) { settext("Hello") setGeometry(300,300,100,100) } label2 = new qlabel(win1) { settext("How are you ?") setGeometry(100,100,100,100) } dock1 = new qdockwidget(win1,0) { setwidget(label1) SetAllowedAreas(1) } dock2 = new qdockwidget(win1,0) { setwidget(label2) SetAllowedAreas(2) } adddockwidget(Qt_LeftDockWidgetArea,dock1,Qt_Horizontal) adddockwidget(Qt_LeftDockWidgetArea,dock2,Qt_Vertical) show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot12.jpg :alt: QDockWidget .. index:: pair: RingQt によるデスクトップとモバイル開発; QTabWidget の用法 QTabWidget の用法 ===================== この用例では、 QTabWidget クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("Using QTabWidget") setGeometry(100,100,400,400) page1 = new qwidget() { new qpushbutton(page1) { settext("The First Page") } } page2 = new qwidget() { new qpushbutton(page2) { settext("The Second Page") } } page3 = new qwidget() { new qpushbutton(page3) { settext("The Third Page") } } tab1 = new qtabwidget(win1) { inserttab(0,page1,"Page 1") inserttab(1,page2,"Page 2") inserttab(2,page3,"Page 3") setGeometry(100,100,400,400) } status1 = new qstatusbar(win1) { showmessage("Ready!",0) } setstatusbar(status1) showMaximized() } exec() } 実行中のアプリケーション .. image:: ringqt_shot13.jpg :alt: QTabWidget .. index:: pair: RingQt によるデスクトップとモバイル開発; QTableWidget の用法 QTableWidget の用法 ======================= この用例では、 QTableWidget クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setGeometry(100,100,1100,370) setwindowtitle("Using QTableWidget") Table1 = new qTableWidget(win1) { setrowcount(10) setcolumncount(10) setGeometry(0,0,800,400) setselectionbehavior(QAbstractItemView_SelectRows) for x = 1 to 10 for y = 1 to 10 item1 = new qtablewidgetitem("R"+X+"C"+Y) setitem(x-1,y-1,item1) next next } setcentralwidget(table1) show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot14.jpg :alt: QTableWidget .. index:: pair: RingQt によるデスクトップとモバイル開発; QProgressBar の用法 QProgressBar の用法 ======================= この用例では、 QProgressBar クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setGeometry(100,100,600,150) setwindowtitle("Using QProgressBar") for x = 10 to 100 step 10 new qprogressbar(win1) { setGeometry(100,x,350,30) setvalue(x) } next show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot15.jpg :alt: QProgressBar .. index:: pair: RingQt によるデスクトップとモバイル開発; QSpinBox の用法 QSpinBox の用法 =================== この用例では、 QSpinBox クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setGeometry(100,100,450,260) setwindowtitle("Using QSpinBox") new qspinbox(win1) { setGeometry(50,100,350,30) setvalue(50) } show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot16.jpg :alt: QSpinBox .. index:: pair: RingQt によるデスクトップとモバイル開発; QSlider の用法 QSlider の用法 ================== この用例では、 QSlider クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setGeometry(100,100,500,400) setwindowtitle("Using QSlider") new qslider(win1) { setGeometry(100,100,50,130) settickinterval(50) } new qslider(win1) { setGeometry(100,250,250,30) settickinterval(50) setorientation(Qt_Horizontal) } show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot17.jpg :alt: QSlider .. index:: pair: RingQt によるデスクトップとモバイル開発; QDateEdit の用法 QDateEdit の用法 ==================== この用例では、 QDateEdit クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("Using QDateEdit") setGeometry(100,100,250,100) new qdateedit(win1) { setGeometry(20,40,220,30) } show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot18.jpg :alt: QDateEdit .. index:: pair: RingQt によるデスクトップとモバイル開発; QDial の用法 QDial の用法 ================ この用例では、 QDial クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setGeometry(100,100,450,500) setwindowtitle("Using QDial") new qdial(win1) { setGeometry(100,100,250,300) } show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot19.jpg :alt: QDial その他の用例: .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setGeometry(100,100,450,500) setwindowtitle("Using QDial") button1 = new QPushButton(win1){ setGeometry(100,350,100,30) settext("Increment") setClickEvent("pIncrement()") } button2 = new QPushButton(win1){ setGeometry(250,350,100,30) settext("Decrement") setClickEvent("pDecrement()") } pdial = new qdial(win1) { setGeometry(100,50,250,300) setNotchesVisible(true) setValue(50) SetValueChangedEvent("pDialMove()") } lineedit1 = new qlineedit(win1) { setGeometry(200,400,50,30) setalignment(Qt_AlignHCenter) settext(string(pdial.value())) setreturnPressedEvent("pPress()") } show() } exec() } func pIncrement pdial{val=value()} pdial.setvalue(val+1) lineedit1{settext(string(val+1))} func pDecrement pdial{val=value()} pdial.setvalue(val-1) lineedit1{settext(string(val-1))} func pPress lineedit1{val=text()} pdial.setvalue(number(val)) func pDialMove lineedit1.settext(""+pdial.value()) .. image:: usingqdial.png :alt: QDial - 第二用例 .. index:: pair: RingQt によるデスクトップとモバイル開発; QWebView の用法 QWebView の用法 =================== この用例では、 QWebView クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("QWebView") myweb = new qwebview(win1) { setGeometry(10,10,600,600) loadpage(new qurl("http://google.com")) } setcentralwidget(myweb) showMaximized() } exec() } 実行中のアプリケーション .. image:: ringqt_shot20.jpg :alt: QWebView .. index:: pair: RingQt によるデスクトップとモバイル開発; QCheckBox の用法 QCheckBox の用法 ==================== この用例では、 QCheckBox クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("Using QCheckBox") new qcheckbox(win1) { setGeometry(100,100,100,30) settext("New Customer!") } showMaximized() } exec() } 実行中のアプリケーション .. image:: ringqt_shot21.jpg :alt: QCheckBox その他の用例: .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setGeometry(100,100,400,300) setwindowtitle("Using QCheckBox") ### 0: チェックされていない。 1: チェックされた。 CheckBox = new qcheckbox(win1) { setGeometry(100,100,160,30) settext("New Customer!") setclickedEvent("HandleClickEvent()") } show() } exec() } Func HandleClickEvent if CheckBox.isChecked() = 1 CheckBox.settext("New Customer. Check 1-ON") else CheckBox.settext("New Customer. Check 0-OFF") ok .. index:: pair: RingQt によるデスクトップとモバイル開発; QRadioButton と QButtonGroup の用法 QRadioButton と QButtonGroup の用法 ======================================= この用例では、 QRadioButton および QButtonGroup クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("Using QRadioButton") new qradiobutton(win1) { setGeometry(100,100,100,30) settext("One") } new qradiobutton(win1) { setGeometry(100,150,100,30) settext("Two") } new qradiobutton(win1) { setGeometry(100,200,100,30) settext("Three") } group2 = new qbuttongroup(win1) { btn4 = new qradiobutton(win1) { setGeometry(200,150,100,30) settext("Four") } btn5 = new qradiobutton(win1) { setGeometry(200,200,100,30) settext("Five") } addbutton(btn4,0) addbutton(btn5,0) } showMaximized() } exec() } 実行中のアプリケーション .. image:: ringqt_shot22.jpg :alt: QRadioButton と QButtonGroup の用法 .. index:: pair: RingQt によるデスクトップとモバイル開発; QLabel へハイパーリンクを追加するには QLabel へハイパーリンクを追加するには ===================================== この用例では、 QLabel クラスでハイパーリンクを作成する方法を学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("QLabel - Hyperlink") new qlabel(win1) { setGeometry(100,100,100,30) setopenexternallinks(true) settext('Google') } showMaximized() } exec() } 実行中のアプリケーション .. image:: ringqt_shot23.jpg :alt: ハイパーリンク .. index:: pair: RingQt によるデスクトップとモバイル開発; QVideoWidget と QMediaPlayer QVideoWidget と QMediaPlayer ============================= この用例では、 QVideoWidget および QMediaPlayer クラスで動画のグループを 異なる位置から同時再生する方法を学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("QVideoWidget") btn1 = new qpushbutton(win1) { setGeometry(0,0,100,30) settext("play") setclickevent("player.play() player2.play() player3.play() player4.play()") } videowidget = new qvideowidget(win1) { setGeometry(50,50,600,300) setstylesheet("background-color: black") } videowidget2 = new qvideowidget(win1) { setGeometry(700,50,600,300) setstylesheet("background-color: black") } videowidget3 = new qvideowidget(win1) { setGeometry(50,370,600,300) setstylesheet("background-color: black") } videowidget4 = new qvideowidget(win1) { setGeometry(700,370,600,300) setstylesheet("background-color: black") } player = new qmediaplayer() { setmedia(new qurl("1.mp4")) setvideooutput(videowidget) setposition(35*60*1000) } player2 = new qmediaplayer() { setmedia(new qurl("2.mp4")) setvideooutput(videowidget2) setposition(23*60*1000) } player3 = new qmediaplayer() { setmedia(new qurl("3.mp4")) setvideooutput(videowidget3) setposition(14.22*60*1000) } player4 = new qmediaplayer() { setmedia(new qurl("4.avi")) setvideooutput(videowidget4) setposition(8*60*1000) } showfullscreen() } exec() } 実行中のアプリケーション .. image:: ringqt_shot24.jpg :alt: QVideoWidget .. index:: pair: RingQt によるデスクトップとモバイル開発; QFrame の用法 QFrame の用法 ================= この用例では、 QFrame クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("Using QFrame") for x = 0 to 10 frame1 = new qframe(win1,0) { setGeometry(100,20+50*x,400,30) setframestyle(QFrame_Raised | QFrame_WinPanel) } next showMaximized() } exec() } 実行中のアプリケーション .. image:: ringqt_shot25.jpg :alt: QFrame .. index:: pair: RingQt によるデスクトップとモバイル開発; QLabel による画像の表示方法 QLabel による画像の表示方法 =============================== QLabel ウイジェットによる画像の表示方法を学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("QLabel - Display image") new qlabel(win1) { image = new qpixmap("b:/mahmoud/photo/advice.jpg") setpixmap(image) setGeometry(0,0,image.width(),image.height()) } showMaximized() } exec() } 実行中のアプリケーション .. image:: ringqt_shot26.jpg :alt: 画像の表示 .. index:: pair: RingQt によるデスクトップとモバイル開発; メニューバーとスタイルシートの用例 メニューバーとスタイルシートの用例 ================================== メニューバーの作成、およびウィンドウのスタイルシートの設定方法を学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("Menubar") menu1 = new qmenubar(win1) { sub1 = addmenu("File") sub1 { oAction = new qAction(win1) { settext("New") setenabled(false) } addaction(oAction) oAction = new qAction(win1) { settext("Open") setcheckable(true) setchecked(true) setstatustip("open new file") } addaction(oAction) oAction = new qAction(win1) { settext("Save") } addaction(oAction) oAction = new qAction(win1) { settext("Save As") } addaction(oAction) addseparator() oAction = new qaction(win1) oAction.settext("Exit") oAction.setclickevent("myapp.quit()") addaction(oAction) } } status1 = new qstatusbar(win1) { showmessage("Ready!",0) } setmenubar(menu1) setmousetracking(true) setstatusbar(status1) setStyleSheet("color: black; selection-color: black; selection-background-color:white ; background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #eef, stop: 1 #ccf);") showmaximized() } exec() } 実行中のアプリケーション .. image:: ringqt_shot27.jpg :alt: メニューバー .. index:: pair: RingQt によるデスクトップとモバイル開発; QLineEdit イベントと QMessageBox QLineEdit イベントと QMessageBox ================================ QLineEdit イベントの用法、およびメッセージボックスの表示方法を学びます。 .. code-block:: ring Load "guilib.ring" MyApp = New qApp { win1 = new qWidget() { setwindowtitle("Welcome") setGeometry(100,100,400,300) label1 = new qLabel(win1) { settext("What is your name ?") setGeometry(10,20,350,30) setalignment(Qt_AlignHCenter) } btn1 = new qpushbutton(win1) { setGeometry(10,200,100,30) settext("Say Hello") setclickevent("pHello()") } btn1 = new qpushbutton(win1) { setGeometry(150,200,100,30) settext("Close") setclickevent("pClose()") } lineedit1 = new qlineedit(win1) { setGeometry(10,100,350,30) settextchangedevent("pChange()") setreturnpressedevent("penter()") } show() } exec() } Func pHello lineedit1.settext( "Hello " + lineedit1.text()) Func pClose MyApp.quit() Func pChange win1 { setwindowtitle( lineedit1.text() ) } Func pEnter new qmessagebox(win1) { setwindowtitle("Thanks") settext("Hi " + lineedit1.text() ) setstylesheet("background-color : white") show() } 実行中のアプリケーション .. image:: ringqt_shot28.jpg :alt: QLineEdit イベントと QMessageBox .. image:: ringqt_shot29.jpg :alt: QLineEdit イベントと QMessageBox .. index:: pair: RingQt によるデスクトップとモバイル開発; そのほかのウイジェットイベント そのほかのウイジェットイベント ============================== 各 Qt シグナルは RingQt で使えます。シグナル名の前に設定を行うことで追加、 およびイベントのコードを決定するために使用できるメソッドを取得するためにシグナル名の後にイベントを追加します。 例えば QProgressBar クラスにはシグナル名である valueChanged() があります。 使用するには setValueChangedEvent() 関数を使用します。 用例: .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("QProgressBar valueChanged Event") progress1 = new qprogressbar(win1) { setGeometry(100,100,350,30) setvalue(10) setvaluechangedevent("pChange()") } new qpushbutton(win1) { setGeometry(10,10,100,30) settext("increase") setclickevent("pIncrease()") } showMaximized() } exec() } func pIncrease progress1 { setvalue(value()+1) } func pchange win1.setwindowtitle("value : " + progress1.value() ) 実行中のアプリケーション .. image:: ringqt_shot30.jpg :alt: qProgressBar クラスの valueChanged イベント 別の用例は QCheckBox クラスの stateChanged イベントです。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qMainWindow() { setwindowtitle("QCheckBox") new qcheckbox(win1) { setGeometry(100,100,100,30) settext("New Customer!") setstatechangedevent("pchange()") } showMaximized() } exec() } Func pChange new qMessageBox(Win1) { setWindowTitle("Checkbox") settext("State Changed!") show() } 実行中のアプリケーション .. image:: ringqt_shot31.jpg :alt: qProgressBar クラスの valueChanged イベント .. index:: pair: RingQt によるデスクトップとモバイル開発; QTimer クラスの用法 QTimer クラスの用法 ======================= この用例では、 QTimer クラスを学びます。 .. code-block:: ring Load "guilib.ring" new qApp { win1 = new qwidget() { setgeometry(100,100,200,70) setwindowtitle("Timer") label1 = new qlabel(win1) { setgeometry(10,10,200,30) settext(thetime()) } new qtimer(win1) { setinterval(1000) settimeoutevent("pTime()") start() } show() } exec() } func ptime label1.settext(thetime()) Func thetime return "Time : " + Time() 実行中のアプリケーション .. image:: ringqt_shot32.jpg :alt: QTimer クラス .. index:: pair: RingQt によるデスクトップとモバイル開発; QProgressBar およびタイマーの用法 QProgressBar およびタイマーの用法 ===================================== この用例では、“アニメーション”つきの QProgressBar クラスとタイマーを学びます。 .. code-block:: ring ###------------------------------------ ### プログレスバーとタイマーの用例 Load "guilib.ring" new qApp { win1 = new qwidget() { setgeometry(100,100,400,100) setwindowtitle("Timer and ProgressBar") LabelMan = new qlabel(win1) { setgeometry(10,10,200,30) settext(theTime()) ### ==>> 関数 } TimerMan = new qtimer(win1) { setinterval(1000) settimeoutevent("pTime()") ### ==>> 関数 start() } BarMan = new qprogressbar(win1) { setGeometry(100,50,300,10) ### X, Y 位置、長さ、チックネス setvalue(0) ### パーセントが塗りつぶされた } show() } exec() } func pTime LabelMan.settext(theTime()) ### ==>> 関数 Increment = 10 if BarMan.value() >= 100 ### プログレスバーの開始後. BarMan.setvalue(0) ok BarMan{ setvalue(value() + Increment) } Func theTime return "Time : " + Time() .. image:: ringqt_shot15-B.jpg :alt: QProgressBar .. index:: pair: RingQt によるデスクトップとモバイル開発; QLabel による寸法変更画像の表示方法 QLabel による寸法変更画像の表示方法 ======================================= この例では QLabel ウィジェットで“アニメーションつき”の画像を表示して寸法を変更する方法を学びます。 .. code-block:: ring Load "guilib.ring" #---------------------------------------------------- # 必携: image = "C:\RING\bin\stock.jpg" # imageStock: 伸張する画像の開始寸法 imageW = 200 ; imageH = 200 ; GrowBy = 4 ###---------------------------------------------------- ### ウィンドウと箱の大きさの寸法 WinWidth = 1280 ; WinHeight = 960 BoxWidth = WinWidth -80 ; BoxHeight = WinHeight -80 ###---------------------------------------------------- New qapp { win1 = new qwidget() { setgeometry(50,50, WinWidth,WinHeight) setwindowtitle("Animated Image - Display Image Scaled and Resized") imageStock = new qlabel(win1) { image = new qpixmap("C:\RING\bin\stock.jpg") AspectRatio = image.width() / image.height() imageW = 200 imageH = imageH / AspectRatio ### 水平寸法、垂直寸法、アスペクト比、変形 setpixmap(image.scaled(imageW , imageH ,0,0)) PosLeft = (BoxWidth - imageW ) / 2 PosTop = (BoxHeight - imageH ) / 2 setGeometry(PosLeft,PosTop,imageW,imageH) } TimerMan = new qtimer(win1) { setinterval(100) ### 100 ミリ秒間隔です。 settimeoutevent("pTime()") ### ==>> 関数 start() } show() } exec() } ###------------------------------------------------------ ### TimerMan 関数: 100 ミリ秒間隔で呼び出します。 func pTime ### 画像の大きさがウィンドウ領域に達したときにタイマーを停止します。 if imageW > BoxWidth TimerMan.stop() imageStock.clear() ### 画像の消去 ok ## 画像の伸張 imageW += GrowBy imageH = imageW / AspectRatio ### 画像の寸法変更: 水平寸法、垂直寸法、アスペクト比、変形 imageStock.setpixmap(image.scaled(imageW , imageH ,0,0)) ### 画像を中央へ PosLeft = (WinWidth - imageW ) / 2 PosTop = (WinHeight - imageH ) / 2 imageStock.setGeometry(PosLeft,PosTop,imageW,imageH) .. index:: pair: RingQt によるデスクトップとモバイル開発; QFileDialog クラスの用法 QFileDialog クラスの用法 ============================ 用例: .. code-block:: ring Load "guilib.ring" New qapp { win1 = new qwidget() { setwindowtitle("open file") setgeometry(100,100,400,400) new qpushbutton(win1) { setgeometry(10,10,200,30) settext("open file") setclickevent("pOpen()") } show() } exec() } Func pOpen new qfiledialog(win1) { cName = getopenfilename(win1,"open file","c:\","source files(*.ring)") win1.setwindowtitle(cName) } 実行中のアプリケーション .. image:: ringqt_shot33.jpg :alt: QFileDialog クラス .. index:: pair: RingQt によるデスクトップとモバイル開発; QPainter による描画方法 QPainter による描画方法 =========================== この用例では、 QPainter クラスによる描画方法を学びます。 .. code-block:: ring Load "guilib.ring" New qapp { win1 = new qwidget() { setwindowtitle("Drawing using QPainter") setgeometry(100,100,500,500) label1 = new qlabel(win1) { setgeometry(10,10,400,400) settext("") } new qpushbutton(win1) { setgeometry(200,400,100,30) settext("draw") setclickevent("draw()") } show() } exec() } Func draw p1 = new qpicture() color = new qcolor() { setrgb(0,0,255,255) } pen = new qpen() { setcolor(color) setwidth(10) } new qpainter() { begin(p1) setpen(pen) drawline(500,150,950,450) drawline(950,550,500,150) endpaint() } label1 { setpicture(p1) show() } 実行中のアプリケーション .. image:: ringqt_shot34.jpg :alt: QPainter クラス .. index:: pair: RingQt によるデスクトップとモバイル開発; QPrinter による印刷方法 QPrinter による印刷方法 =========================== この用例では、 QPrinter で PDF ファイルを印刷する方法を学びます。 .. code-block:: ring Load "guilib.ring" new qApp { win1 = new qwidget() { setwindowtitle("Printer") setgeometry(100,100,500,500) myweb = new qwebview(win1) { setgeometry(100,100,1000,500) loadpage(new qurl("http://google.com")) } new qpushbutton(win1) { setGeometry(20,20,100,30) settext("Print") setclickevent("print()") } showmaximized() } exec() } func print printer1 = new qPrinter(0) { setoutputformat(1) # 1 = pdf setoutputfilename("test.pdf") painter = new qpainter() { begin(printer1) myfont = new qfont("Times",50,-1,0) setfont(myfont) drawtext(100,100,"test") printer1.newpage() drawtext(100,100,"test2") endpaint() } } printer1 = new qPrinter(0) { setoutputformat(1) setoutputfilename("test2.pdf") myweb.print(printer1) myweb.show() } system ("test.pdf") system ("test2.pdf") .. index:: pair: RingQt によるデスクトップとモバイル開発; QPrintPreviewDialog の用法 QPrintPreviewDialog の用法 ============================== この用例では、 QPrintPreviewDialog クラスの用法を学びます。 用例: .. code-block:: ring load "guilib.ring" new qApp { win1 = new qwidget() { setwindowtitle("Printer Preview Dialog") setgeometry(100,100,800,880) printer1 = new qPrinter(0) show() oPreview = new qPrintPreviewDialog(printer1) { setParent(win1) move(10,10) setPaintrequestedevent("printPreview()") exec() } } exec() } func printPreview printer1 { painter = new qpainter() { begin(printer1) myfont = new qfont("Times",50,-1,0) setfont(myfont) drawtext(100,100,"Test - Page (1)") printer1.newpage() drawtext(100,100,"Test - Page (2)") printer1.newpage() myfont2 = new qfont("Times",14,-1,0) setfont(myfont2) for x = 1 to 30 drawtext(100,100+(20*x),"Number : " + x) next endpaint() } } スクリーンショット: .. image:: printpreviewdialog.png :alt: 印刷プレビューのダイアログ .. index:: pair: RingQt によるデスクトップとモバイル開発; 複数ウィンドウの作成方法 複数ウィンドウの作成方法 ======================== この用例は、複数ウィンドウの作成をするためのデモです。 .. code-block:: ring Load "guilib.ring" app1 = new qapp { win1 = new qwidget() { setwindowtitle("First") setgeometry(100,100,500,500) new qpushbutton(win1) { setgeometry(100,100,100,30) settext("close") setclickevent("app1.quit()") } new qpushbutton(win1) { setgeometry(250,100,100,30) settext("Second") setclickevent("second()") } showmaximized() } exec() } func second win2 = new qwidget() { setwindowtitle("Second") setgeometry(100,100,500,500) setwindowflags(Qt_dialog) show() } 実行中のアプリケーション .. image:: ringqt_shot35.jpg :alt: 複数ウィンドウの作成方法 .. index:: pair: RingQt によるデスクトップとモバイル開発; 音声の再生 音声の再生 ============= 用例: .. code-block:: ring Load "guilib.ring" new qapp { win1 = new qwidget() { setwindowtitle("play sound!") show() } new qmediaplayer() { setmedia(new qurl("footstep.wav")) setvolume(50) play() } exec() } .. index:: pair: RingQt によるデスクトップとモバイル開発; QColorDialog クラスの用法 QColorDialog クラスの用法 ============================= 用例: .. code-block:: ring Load "guilib.ring" oApp = new myapp { start() } Class MyApp oColor win1 Func start myapp = new qapp win1 = new qMainWindow() { setwindowtitle("Color Dialog") setgeometry(100,100,400,400) } new qpushbutton(win1) { setgeometry(10,10,100,30) settext("Get Color") setclickevent("oApp.pColor()") } win1.show() myapp.exec() Func pColor myobj = new qcolordialog() aColor = myobj.GetColor() r=acolor[1] g=acolor[2] b=acolor[3] win1.setstylesheet("background-color: rgb("+r+", " + g+ "," + b + ")") 実行中のアプリケーション .. image:: ringqt_shot37.jpg :alt: QColorDialog クラス .. index:: pair: RingQt によるデスクトップとモバイル開発; qLCDNumber クラスの用法 qLCDNumber クラスの用法 =========================== この用例では、 qLCDNumber クラスを学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = new qWidget() { setwindowtitle("LCD Number") setgeometry(100,100,250,120) new qLCDNumber(win1) { setgeometry(10,10,100,40) display(100) } new qLCDNumber(win1) { setgeometry(10,60,100,40) display(80) } show() } exec() } 実行中のアプリケーション .. image:: ringqt_shot38.jpg :alt: QLCDNumber クラス .. index:: pair: RingQt によるデスクトップとモバイル開発; 移動可能ラベルの用例 移動可能ラベルの用例 ====================== .. code-block:: ring Load "guilib.ring" new qApp { win1 = new qWidget() { label1 = new qLabel(win1) { setText("Welcome") setgeometry(10,10,200,50) setstylesheet("color: purple ; font-size: 30pt;") } new qTimer(win1) { setInterVal(10) setTimeOutEvent("pMove()") start() } setWindowTitle("Movable Label") setgeometry(100,100,600,80) setStyleSheet("background-color: white;") show() } exec() } Func pMove label1 { move(x()+1,y()) if x() > 600 move(10,y()) ok } 実行中のアプリケーション .. image:: ringqt_shot39.jpg :alt: 移動可能ラベル .. index:: pair: RingQt によるデスクトップとモバイル開発; QMessagebox の用例 QMessagebox の用例 =================== メッセージ・ボックスの出力を確認する方法を学びます。 .. code-block:: ring Load "guilib.ring" new qApp { win1 = new qWidget() { label1 = new qpushbutton(win1) { setText("Test") setgeometry(10,10,200,50) setstylesheet("color: purple ; font-size: 30pt;") setclickevent("pWork()") } setWindowTitle("Messagebox") setgeometry(100,100,600,80) setStyleSheet("background-color: white;") show() } exec() } func pWork new qmessagebox(win1) { setwindowtitle("messagebox title") settext("messagebox text") setInformativeText("Do you want to save your changes?") setstandardbuttons(QMessageBox_Yes | QMessageBox_No | QMessageBox_Close) result = exec() win1 { if result = QMessageBox_Yes setwindowtitle("Yes") but result = QMessageBox_No setwindowtitle("No") but result = QMessageBox_Close setwindowtitle("Close") ok } } 実行中のアプリケーション .. image:: ringqt_shot40.jpg :alt: QMessageBox の実行結果 .. index:: pair: RingQt によるデスクトップとモバイル開発; QInputDialog クラスの用法 QInputDialog クラスの用法 ============================= この用例では、 QInputDialog クラスの用法を学びます。 .. code-block:: ring Load "guilib.ring" New QApp { Win1 = New QWidget () { SetGeometry(100,100,400,400) SetWindowTitle("Input Dialog") New QPushButton(win1) { SetText ("Input Dialog") SetGeometry(100,100,100,30) SetClickEvent("pWork()") } Show() } exec() } Func pWork oInput = New QInputDialog(win1) { setwindowtitle("What is your name?") setgeometry(100,100,400,50) setlabeltext("User Name") settextvalue("Mahmoud") lcheck = exec() if lCheck win1.setwindowtitle(oInput.textvalue()) ok } 実行中のアプリケーション .. image:: ringqt_shot41.jpg :alt: QInputDialog .. index:: pair: RingQt によるデスクトップとモバイル開発; ダイアログ関数 ダイアログ関数 ============== この関数があります。 .. code-block:: none SetDialogIcon(cIconFile) MsgInfo(cTitle,cMessage) ConfirmMsg(cTitle,cMessage) --> lResult InputBox(cTitle,cMessage) --> cValue InputBoxInt(cTitle,cMessage) --> nValue InputBoxNum(cTitle,cMessage) --> nValue InputBoxPass(cTitle,cMessage) --> cValue 用例 .. code-block:: ring load "guilib.ring" new qApp { SetDialogIcon("notepad.png") msginfo(:Ring,:Welcome) see confirmMsg(:Ring,"Are you sure?") + nl see InputBoxNum(:Ring,"Enter Number(double) :") + nl see InputBox(:Ring,"Enter Value :") + nl see InputBoxInt(:Ring,"Enter Number(int)") + nl see InputBoxPass(:Ring,"Enter Password") +nl } .. index:: pair: RingQt によるデスクトップとモバイル開発; キー入力とマウス移動イベント キー入力とマウス移動イベント ============================== この用例では、イベントフィルタによりキー入力と マウスの移動イベントを検知するための方法を学びます。 .. code-block:: ring Load "guilib.ring" new qApp { win1 = new qWidget() { setWindowTitle("Test using Event Filter!") setGeometry(100,100,400,400) setmousetracking(true) myfilter = new qallevents(win1) myfilter.setKeyPressEvent("pWork()") myfilter.setMouseButtonPressevent("pClick()") myfilter.setmousemoveevent("pMove()") installeventfilter(myfilter) show() } exec() } func pWork win1.setwindowtitle('KeyPress! : ' + myfilter.getkeycode()) func pClick new qmessagebox(win1) { setgeometry(100,100,400,100) setwindowtitle("click event!") settext("x : " + myfilter.getx() + " y : " + myfilter.gety() + " button : " + myfilter.getbutton() ) show() } func pMove win1.setwindowtitle("Mouse Move , X : " + myfilter.getx() + " Y : " + myfilter.gety() ) 実行中のアプリケーション .. image:: ringqt_shot42.jpg :alt: キー入力とマウス移動イベント .. index:: pair: RingQt によるデスクトップとモバイル開発; マウスによるオブジェクトの移動方法 マウスによるオブジェクトの移動方法 ====================================== ユーザがラベルを移動できる移動可能なオブジェクトをプログラムする方法を学びます。 .. code-block:: ring Load "guilib.ring" lPress = false nX = 0 nY = 0 new qApp { win1 = new qWidget() { setWindowTitle("Move this label!") setGeometry(100,100,400,400) setstylesheet("background-color:white;") Label1 = new qLabel(Win1){ setGeometry(100,100,200,50) setText("Welcome") setstylesheet("font-size: 30pt") myfilter = new qallevents(label1) myfilter.setEnterevent("pEnter()") myfilter.setLeaveevent("pLeave()") myfilter.setMouseButtonPressEvent("pPress()") myfilter.setMouseButtonReleaseEvent("pRelease()") myfilter.setMouseMoveEvent("pMove()") installeventfilter(myfilter) } show() } exec() } Func pEnter Label1.setStyleSheet("background-color: purple; color:white;font-size: 30pt;") Func pLeave Label1.setStyleSheet("background-color: white; color:black;font-size: 30pt;") Func pPress lPress = True nX = myfilter.getglobalx() ny = myfilter.getglobaly() Func pRelease lPress = False pEnter() Func pMove nX2 = myfilter.getglobalx() ny2 = myfilter.getglobaly() ndiffx = nX2 - nX ndiffy = nY2 - nY if lPress Label1 { move(x()+ndiffx,y()+ndiffy) setStyleSheet("background-color: Green; color:white;font-size: 30pt;") nX = nX2 ny = nY2 } ok 実行中のアプリケーション .. image:: ringqt_shot43.jpg :alt: マウスで移動できるオブジェクト .. image:: ringqt_shot44.jpg :alt: マウスで移動できるオブジェクト .. image:: ringqt_shot45.jpg :alt: マウスをで移動できるオブジェクト .. index:: pair: RingQt によるデスクトップとモバイル開発; GUI クラスからの継承 GUI クラスからの継承 ============================ 用例: .. code-block:: ring Load "guilib.ring" New MyWindow() new qApp { exec() } class mywindow from qwidget Func init super.init() setwindowtitle("First Window") setgeometry(100,100,400,400) setstylesheet("background-color: purple;") settooltip("my first window!") show() 実行中のアプリケーション .. image:: ringqt_shot46.jpg :alt: GUI クラスからの継承 .. index:: pair: RingQt によるデスクトップとモバイル開発; QDesktopWidget クラスの用法 QDesktopWidget クラスの用法 =============================== この用例では、 QDesktopWidget の用法を学びます。 .. code-block:: ring Load "guilib.ring" New qApp { win1 = New qWidget() { resize(400,400) btn1 = new qPushbutton(win1) { setText("Center") move(100,100) resize(100,30) setClickEvent("pCenter()") } Show() } exec() } Func pCenter oDesktop = new qDesktopWidget() oRect = oDesktop.screenGeometry( oDesktop.primaryScreen() ) win1.move((oRect.width()-win1.width()) /2 , (oRect.Height()-win1.Height())/2 ) win1.show() 実行中のアプリケーション .. image:: ringqt_shot47.jpg :alt: Using QDesktopWidget クラス .. index:: pair: RingQt によるデスクトップとモバイル開発; テキストの回転 テキストの回転 ============== この用例では、タイマーでテキストを回転しています。 .. code-block:: ring Load "guilib.ring" nAngle = 0 New qapp { win1 = new qwidget() { setwindowtitle("Rotate Text") resize(800,600) label1 = new qlabel(win1) { settext("") myfilter = new qallevents(win1) myfilter.setMouseButtonPressevent("pClick()") installeventfilter(myfilter) } new qtimer(win1) { setinterval(50) settimeoutevent("pTime()") start() } pDraw() L1 = new qVBoxLayout() { AddWidget(Label1) } SetLayout(L1) showMaximized() } exec() } Func pDraw p1 = new qpicture() color = new qcolor() { setrgb(0,0,255,255) } pen = new qpen() { setcolor(color) setwidth(50) } painter = new qpainter() { begin(p1) setpen(pen) myfont = font() myfont.setpointsize(50) setfont(myfont) rotate(nAngle) drawtext(350,0*nAngle,"welcome") drawtext(0,0*nAngle,"welcome") endpaint() } label1 { setpicture(p1) show() } Func pClick win1 { setwindowtitle("Click Event") } Func pTime nAngle++ if nAngle = 90 nAngle = 10 ok pDraw() 実行中のアプリケーション .. image:: shotrotatetext.png :alt: テキスト回転の用例 .. index:: pair: RingQt によるデスクトップとモバイル開発; フォーカスの変更 フォーカスの変更 ================ この用例は、 ENTER キーでフォーカスを変更します。 .. code-block:: ring load "guilib.ring" new qApp { win = new qWidget() { resize(600,600) SetWindowTitle("Change Focus") text1 = new qLineEdit(win) text2 = new qLineEdit(win) text3 = new qLineEdit(win) text4 = new qLineEdit(win) layout1 = new qVBoxLayout() { AddWidget(text1) AddWidget(text2) AddWidget(text3) AddWidget(text4) } setLayout(Layout1) aList = [text1,text2,text3,text4] oFilter = new qallevents(win) oFilter.setKeyPressEvent("pWork()") installeventfilter(oFilter) show() } exec() } func pWork nCode = oFilter.getkeycode() if nCode = 16777220 # ENTER キー for x=1 to len(aList) if aList[x].HasFocus() t = x+1 if t > len(aList) t=1 ok aList[t].SetFocus(0) exit ok next ok .. index:: pair: RingQt によるデスクトップとモバイル開発; 正規表現 正規表現 ======== この用例では、正規表現のクラスを使用しています。 .. code-block:: ring load "guilib.ring" new qApp { see "Using Regular Expressions" + nl exp = new qregularexpression() { setPattern("\d\d \w+") see pattern() + nl match = match("33 one",0,0,0) see match.hasmatch() + nl match = match("3 one",0,0,0) see match.hasmatch() + nl match = match("welcome 11 one",0,0,0) see match.hasmatch() + nl matched = match.captured(0) see matched + nl } exp = new qregularexpression() { setPattern("^(\d\d)/(\d\d)/(\d\d\d\d)$") see pattern() + nl match = match("08/12/1985",0,0,0) see match.hasmatch() + nl day = match.captured(1) month = match.captured(2) year = match.captured(3) see day + nl + month + nl + year + nl see "(" + match.capturedStart(1) + "," + match.capturedEnd(1)+ ")" + nl see "(" + match.capturedStart(2) + "," + match.capturedEnd(2)+ ")" + nl see "(" + match.capturedStart(3) + "," + match.capturedEnd(3)+ ")" + nl } } 実行結果: .. code-block:: ring Using Regular Expressions \d\d \w+ 1 0 1 11 one ^(\d\d)/(\d\d)/(\d\d\d\d)$ 1 08 12 1985 (0,2) (3,5) (6,10) .. index:: pair: RingQt によるデスクトップとモバイル開発; シンプルなクライアントとサーバーの用例 シンプルなクライアントとサーバーの用例 ====================================== この用例では、シンプルなクライアントとサーバーアプリケーションの作成方法を学びます。 .. code-block:: ring Load "guilib.ring" new qApp { oClient = new Client { client() } oServer = new Server { server() } exec() } Class Client win1 lineedit1 cOutput="" oTcpSocket func client win1 = new qwidget() new qpushbutton(win1) { setgeometry(50,50,100,30) settext("connect") setclickevent("oClient.Connect()") } lineedit1 = new qtextedit(win1) { setGeometry(150,50,200,300) } win1 { setwindowtitle("client") setgeometry(10,100,400,400) show() } func connect cOutput = "Connect to host 127.0.0.1 port 9999" + nl lineedit1.settext(cOutput) oTcpSocket = new qTcpSocket(win1) { setconnectedevent("oClient.pConnected()") setreadyreadevent("oClient.pRead()") connecttohost("127.0.0.1",9999,3,0) waitforconnected(5000) } func pConnected cOutput += "Connected!" + nl lineedit1.settext(cOutput) func pRead cOutput += "Ready Read!" + nl lineedit1.settext(cOutput) cOutput += oTcpSocket.readall().data() + nl lineedit1.settext(cOutput) Class Server win1 lineedit1 oTcpServer oTcpClient cOutput = "" func server win1 = new qwidget() lineedit1 = new qtextedit(win1) { setGeometry(150,50,200,300) } win1 { setwindowtitle("Server") setgeometry(450,100,400,400) show() } oTcpServer = new qTcpServer(win1) { setNewConnectionEvent("oServer.pNewConnection()") oHostAddress = new qHostAddress() oHostAddress.SetAddress("127.0.0.1") listen(oHostAddress,9999) } cOutput = "Server Started" + nl + "listen to port 9999" + nl lineedit1.settext(cOutput) Func pNewConnection oTcpClient = oTcpServer.nextPendingConnection() cOutput += "Accept Connection" + nl lineedit1.settext(cOutput) oTcpClient { cStr ="Hello from server to client!"+char(13)+char(10) write(cStr,len(cStr)) flush() waitforbyteswritten(300000) close() } 実行中のアプリケーション .. image:: ringqt_shot36.jpg :alt: クライアントとサーバーの用例 .. index:: pair: RingQt によるデスクトップとモバイル開発; 動的オブジェクト 動的オブジェクト ================ 実行時にオブジェクトの作成、およびウィンドウへオブジェクトを追加します。 用例: .. code-block:: ring load "guilib.ring" oFormDesigner = new FormDesigner { start("oFormDesigner") } Class FormDesigner winToolBox winForm aObjects = [] func start cObjectName oApp = new qApp winToolBox = new qWidget() winToolBox.setWindowTitle("ToolBox") winToolBox.move(10,10) winToolBox.resize(300,600) btn = new qPushButton(winToolBox) btn.resize(300,30) btn.setText("Create Button") btn.setClickEvent(cObjectName+".pCreateButton()") btn.show() winToolBox.show() winForm = new qWidget() { move(400,50) setWindowTitle("Form Designer") resize(600,600) show() } oApp.exec() func pCreateButton nCount = len(aObjects) aObjects + new MyButton(winForm) { nIndex = nCount + 1 setText("Button"+ nIndex) Move(30*nIndex,30*nIndex) resize(100,30) show() } Class MyButton from qPushButton nIndex = 0 .. index:: pair: RingQt によるデスクトップとモバイル開発; Weight History アプリケーション Weight History アプリケーション =============================== このサンプルは体重の記録で役に立ちます (日付、時刻と体重)。 .. code-block:: ring Load "guilib.ring" MyApp = new qApp { $ApplicationObject = "oApp" # イベントを呼び出すときに使用します。 oApp = new App exec() oApp.CloseDatabase() } class App cDir = currentdir() + "/" oCon aIDs = [] win1 = new qWidget() { setWindowTitle("Weight History") resize(600,600) layoutButtons = new qhboxlayout() { label1 = new qLabel(win1) { setText("Weight") } text1 = new qlineedit(win1) btnAdd = new qpushbutton(win1) { setText("Add") setClickEvent($ApplicationObject+".AddWeight()") } btnDelete = new qpushbutton(win1) { setText("Delete") setClickEvent($ApplicationObject+".Deleteweight()") } addwidget(label1) addwidget(text1) addwidget(btnAdd) addwidget(btnDelete) } layoutData = new qhboxlayout() { Table1 = new qTableWidget(win1) { setrowcount(0) setcolumncount(3) setselectionbehavior(QAbstractItemView_SelectRows) setHorizontalHeaderItem(0, new QTableWidgetItem("Date")) setHorizontalHeaderItem(1, new QTableWidgetItem("Time")) setHorizontalHeaderItem(2, new QTableWidgetItem("Weight")) setitemChangedEvent($ApplicationObject+".ItemChanged()") setAlternatingRowColors(true) horizontalHeader().setStyleSheet("color: blue") verticalHeader().setStyleSheet("color: red") } addWidget(Table1) } layoutClose = new qhboxlayout() { btnclose = new qpushbutton(win1) { setText("Close") setClickEvent("MyApp.Quit()") } addwidget(btnClose) } layoutMain = new qvboxlayout() { addlayout(layoutButtons) addLayout(LayoutData) addLayout(layoutClose) } setlayout(layoutMain) self.OpenDatabase() self.ShowRecords() show() } Func OpenDatabase lCreate = False if not fexists(cDir + "weighthistory.db") lCreate = True ok new QSqlDatabase() { this.oCon = addDatabase("QSQLITE") { setDatabaseName("weighthistory.db") Open() } } if lCreate new QSqlQuery( ) { exec("create table weighthistory (id integer primary key,"+ " f_date varchar(10),"+ " f_time varchar(8), f_weight varchar(8) );") delete() } ok Func CloseDatabase oCon.Close() Func AddWeight cWeight = text1.text() AddRecord(cWeight) Func DeleteWeight Table1 { nRow = CurrentRow() if nRow >= 0 nID = this.aIDs[nROW+1] new QSqlQuery( ) { exec("delete from weighthistory where id = " + nID ) } Del(this.aIDs,nRow+1) removerow(nRow) selectrow(nRow) ok } Func AddRecord cWeight new QSqlQuery( ) { cStr = "insert into weighthistory (f_date,f_time,f_weight) values"+ " ('%f1','%f2','%f3')" cDate = Date() cTime = Time() cStr = substr(cStr,"%f1",cDate) cStr = substr(cStr,"%f2",cTime) cStr = substr(cStr,"%f3",cWeight) exec(cStr) delete() } ShowRecords() Table1.selectrow(table1.rowcount()-1) Func ShowRecords table1.setitemChangedEvent("") aIDs = [] query = new QSqlQuery() { exec("select * from weighthistory") nRows = 0 this.Table1.setrowcount(0) while movenext() this.table1 { insertRow(nRows) this.aIDs + query.value(0).tostring() for x = 1 to 3 cStr = query.value(x).tostring() item = new qTableWidgetItem(cStr) setItem(nRows,x-1,item) next } nRows++ end delete() } table1.setitemChangedEvent($ApplicationObject+".ItemChanged()") Func ItemChanged nRow = table1.currentrow() if nRow >= 0 myitem = Table1.item(table1.currentrow(),0) cDate = myitem.text() myitem = Table1.item(table1.currentrow(),1) cTime = myitem.text() myitem = Table1.item(table1.currentrow(),2) cWeight = myitem.text() new QSqlQuery( ) { cStr = "update weighthistory set f_date ='%f1' , f_time = '%f2' , "+ "f_weight ='%f3' where id = " + this.aIDs[nROW+1] cStr = substr(cStr,"%f1",cDate) cStr = substr(cStr,"%f2",cTime) cStr = substr(cStr,"%f3",cWeight) exec(cStr) delete() } ok このスクリーンショットはアプリケーション実行中のものです。 .. image:: weighthistory_app.png :alt: Weight History アプリケーション .. index:: pair: RingQt によるデスクトップとモバイル開発; Notepad アプリケーション Notepad アプリケーション ======================== この用例では、 RingQt を使用してシンプルな Notepad を開発したものです。 .. code-block:: ring Load "guilib.ring" cActiveFileName = "" aTextColor = [0,0,0] aBackColor = [255,255,255] cFont = "MS Shell Dlg 2,14,-1,5,50,0,0,0,0,0" cWebsite = "http://www.google.com" oSearch = NULL oSearchValue = NULL oSearchCase = NULL oSearchFilter = NULL oReplaceValue = NULL lAskToSave = false MyApp = New qApp { win1 = new qMainWindow() { setwindowtitle("Ring Notepad") setGeometry(100,100,400,400) aBtns = [ new qpushbutton(win1) { setbtnimage(self,"image/new.png") setclickevent("pNew()") settooltip("New File") } , new qpushbutton(win1) { setbtnimage(self,"image/open.png") setclickevent("pOpen()") settooltip("Open File") } , new qpushbutton(win1) { setbtnimage(self,"image/save.png") setclickevent("pSave()") settooltip("Save") } , new qpushbutton(win1) { setbtnimage(self,"image/saveas.png") setclickevent("pSaveAs()") settooltip("Save As") } , new qpushbutton(win1) { setbtnimage(self,"image/cut.png") setclickevent("pCut()") settooltip("Cut") } , new qpushbutton(win1) { setbtnimage(self,"image/copy.png") setclickevent("pCopy()") settooltip("Copy") } , new qpushbutton(win1) { setbtnimage(self,"image/paste.png") setclickevent("pPaste()") settooltip("Paste") } , new qpushbutton(win1) { setbtnimage(self,"image/font.png") setclickevent("pFont()") settooltip("Font") } , new qpushbutton(win1) { setbtnimage(self,"image/colors.jpg") setclickevent("pColor()") settooltip("Text Color") } , new qpushbutton(win1) { setbtnimage(self,"image/search.png") setclickevent("pFind()") settooltip("Find and Replace") } , new qpushbutton(win1) { setbtnimage(self,"image/print.png") setclickevent("pPrint()") settooltip("Print") } , new qpushbutton(win1) { setbtnimage(self,"image/debug.png") setclickevent("pDebug()") settooltip("Debug (Run then wait!)") } , new qpushbutton(win1) { setbtnimage(self,"image/run.png") setclickevent("pRun()") settooltip("Run the program") } , new qpushbutton(win1) { setbtnimage(self,"image/close.png") setclickevent("pQuit()") settooltip("Quit") } ] tool1 = addtoolbar("files") { for x in aBtns addwidget(x) addseparator() next } menu1 = new qmenubar(win1) { sub1 = addmenu("File") sub2 = addmenu("Edit") sub3 = addmenu("View") sub4 = addmenu("Help") sub1 { oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+n")) setbtnimage(self,"image/new.png") settext("New") setclickevent("pNew()") } addaction(oAction) oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+o")) setbtnimage(self,"image/open.png") settext("Open") setclickevent("pOpen()") } addaction(oAction) addseparator() oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+s")) setbtnimage(self,"image/save.png") settext("Save") setclickevent("pSave()") } addaction(oAction) addseparator() oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+e")) setbtnimage(self,"image/saveas.png") settext("Save As") setclickevent("pSaveAs()") } addaction(oAction) addseparator() oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+p")) setbtnimage(self,"image/print.png") settext("Print to PDF") setclickevent("pPrint()") } addaction(oAction) addseparator() oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+d")) setbtnimage(self,"image/debug.png") settext("Debug (Run then wait!)") setclickevent("pDebug()") } addaction(oAction) addseparator() oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+r")) setbtnimage(self,"image/run.png") settext("Run") setclickevent("pRun()") } addaction(oAction) addseparator() oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+F5")) setbtnimage(self,"image/run.png") settext("Run GUI Application (No Console)") setclickevent("pRunNoConsole()") } addaction(oAction) addseparator() oAction = new qaction(win1) { setShortcut(new QKeySequence("Ctrl+q")) setbtnimage(self,"image/close.png") settext("Exit") setstatustip("Exit") setclickevent("pQuit()") } addaction(oAction) } sub2 { oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+x")) setbtnimage(self,"image/cut.png") settext("Cut") setclickevent("pCut()") } addaction(oAction) oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+c")) setbtnimage(self,"image/copy.png") settext("Copy") setclickevent("pCopy()") } addaction(oAction) oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+v")) setbtnimage(self,"image/paste.png") settext("Paste") setclickevent("pPaste()") } addaction(oAction) addseparator() oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+i")) setbtnimage(self,"image/font.png") settext("Font") setclickevent("pFont()") } addseparator() addaction(oAction) oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+t")) setbtnimage(self,"image/colors.jpg") settext("Text Color") setclickevent("pColor()") } addaction(oAction) oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+b")) setbtnimage(self,"image/colors.jpg") settext("Back Color") setclickevent("pColor2()") } addaction(oAction) addseparator() oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+g")) settext("Go to line") setclickevent("pGoto()") } addaction(oAction) oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+f")) setbtnimage(self,"image/search.png") settext("Find and Replace") setclickevent("pFind()") } addaction(oAction) } sub3 { oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+p")) setbtnimage(self,"image/project.png") settext("Project Files") setclickevent("pProject()") } addaction(oAction) oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+u")) setbtnimage(self,"image/source.png") setclickevent("pSourceCode()") settext("Source Code") } addaction(oAction) oAction = new qAction(win1) { setShortcut(new QKeySequence("Ctrl+w")) setbtnimage(self,"image/richtext.png") setclickevent("pWebBrowser()") settext("Web Browser") } addaction(oAction) } sub4 { sub5 = addmenu("Development Tools") sub5 { oAction = new qAction(win1) { settext("Programming Language") setclickevent("pLang()") } addaction(oAction) oAction = new qAction(win1) { settext("GUI Library") setclickevent("pGUI()") } addaction(oAction) } addseparator() oAction = new qAction(win1) { settext("About") setclickevent("pAbout()") } addaction(oAction) } } setmenubar(menu1) status1 = new qstatusbar(win1) { showmessage("Ready!",0) } setstatusbar(status1) tree1 = new qtreeview(win1) { setclickedevent("pChangeFile()") setGeometry(00,00,200,400) oDir = new QDir() ofile = new QFileSystemModel() { setrootpath(oDir.currentpath()) myfiles = new qstringlist() myfiles.append("*.ring") myfiles.append("*.rh") setnamefilters(myfiles) setNameFilterDisables(false) } setmodel(ofile) myindex = ofile.index(oDir.currentpath(),0) for x = 1 to ofile.columncount() hidecolumn(x) next setcurrentindex(myindex) setexpanded(myindex,true) header().hide() } oDock1 = new qdockwidget(win1,0) { setGeometry(00,00,200,200) setwindowtitle("Project Files") setwidget(tree1) } textedit1 = new qtextedit(win1) { setCursorPositionChangedevent("pCursorPositionChanged()") setLineWrapMode(QTextEdit_NoWrap) setAcceptRichText(false) setTextChangedEvent("lAskToSave = true") } oDock2 = new qdockwidget(win1,0) { setwidget(textedit1) setwindowtitle("Source Code") } oWebBrowser = new qWidget() { setWindowFlags(Qt_SubWindow) oWBLabel = new qLabel(win1) { setText("Website: ") } oWBText = new qLineEdit(win1) { setText(cWebSite) setReturnPressedEvent("pWebGo()") } oWBGo = new qPushButton(win1) { setText("Go") setClickEvent("pWebGo()") } oWBBack = new qPushButton(win1) { setText("Back") setClickEvent("pWebBack()") } oWBLayout1 = new qHBoxLayout() { addWidget(oWBLabel) addWidget(oWBText) addWidget(oWBGo) addWidget(oWBBack) } oWebView = new qWebView(win1) { loadpage(new qurl(cWebSite)) } oWBlayout2 = new qVBoxLayout() { addLayout(oWBLayout1) addWidget(oWebView) } setLayout(oWBLayout2) } oDock3 = new qdockwidget(win1,0) { setwidget(oWebBrowser) setwindowtitle("Web Browser") setFeatures(QDockWidget_DocWidgetClosable) } adddockwidget(1,oDock1,1) adddockwidget(2,oDock2,2) adddockwidget(2,oDock3,1) setwinicon(self,"image/notepad.png") showmaximized() } RestoreSettings() exec() } func pWebGo cWebsite = oWBText.text() oWebView.LoadPage( new qurl( cWebSite ) ) func pWebBack oWebView.Back() func pProject oDock1.Show() func pSourceCode oDock2.Show() func pWebBrowser oDock3.Show() func pChangeFile myitem = tree1.currentindex() if ofile.isdir(myitem) return ok cActiveFileName = ofile.filepath(myitem) textedit1.settext(read(cActiveFileName)) textedit1.setfocus(0) pCursorPositionChanged() pSetActiveFileName() func pSetActiveFileName oDock2.setWindowTitle("Source Code : " + cActiveFileName) func pCursorPositionChanged status1.showmessage(" Line : "+(textedit1.textcursor().blocknumber()+1)+ " Column : " +(textedit1.textcursor().columnnumber()+1) + " Total Lines : " + textedit1.document().linecount() ,0) func pGoto oInput = New QInputDialog(win1) { setwindowtitle("Enter the line number?") setgeometry(100,100,400,50) setlabeltext("Line") settextvalue("1") exec() nLine = 0 + oInput.textvalue() oBlock = textedit1.document().findBlockByLineNumber(nLine-1) oCursor = textedit1.textcursor() oCursor.setposition(oBlock.position(),0) textedit1.settextcursor(oCursor) } func pFind if isobject(oSearch) oSearch.activatewindow() return ok oSearch = new qWidget() { new qLabel(oSearch) { setText("Find What : ") setgeometry(10,10,50,30) } oSearchValue = new qlineedit(oSearch) { setgeometry(80,10,460,30) setReturnPressedEvent("pFindValue()") } new qLabel(oSearch) { setText("Replace with ") setgeometry(10,45,80,30) } oReplaceValue = new qlineedit(oSearch) { setgeometry(80,45,460,30) } oSearchCase = new qCheckbox(oSearch) { setText("Case Sensitive") setgeometry(80,85,100,30) } new qPushButton(oSearch) { setText("Find/Find Next") setgeometry(80,120,100,30) setclickevent("pFindValue()") } new qPushButton(oSearch) { setText("Replace") setgeometry(200,120,100,30) setclickevent("pReplace()") } new qPushButton(oSearch) { setText("Replace All") setgeometry(320,120,100,30) setclickevent("pReplaceAll()") } new qPushButton(oSearch) { setText("Close") setgeometry(440,120,100,30) setclickevent("pSearchClose()") } setwinicon(oSearch,"image/notepad.png") setWindowTitle("Find/Replace") setStyleSheet("background-color:white;") setFixedsize(550,160) setwindowflags( Qt_CustomizeWindowHint | Qt_WindowTitleHint | Qt_WindowStaysOnTopHint) oSearchFilter = new qallevents(oSearch) oSearchFilter.setKeyPressEvent("pSearchKeyPress()") installeventfilter(oSearchFilter) show() } Func pReplace oCursor = textedit1.textCursor() if oCursor.HasSelection() = false new qMessagebox(oSearch) { SetWindowTitle("Replace") SetText("No Selection") show() } return false ok cValue = oSearchValue.text() cSelected = oCursor.SelectedText() if oSearchCase.checkState() = Qt_Unchecked cValue = lower(cValue) cSelected = lower(cSelected) ok if cSelected != cValue new qMessagebox(oSearch) { SetWindowTitle("Replace") SetText("No Match") show() } return false ok cValue = oReplaceValue.text() nStart = oCursor.SelectionStart() nEnd = oCursor.SelectionEnd() cStr = textedit1.toPlainText() cStr = left(cStr,nStart)+cValue+substr(cStr,nEnd+1) textedit1.setText(cStr) return pFindValue() Func pReplaceAll cStr = textedit1.toPlainText() cOldValue = oSearchValue.text() cNewValue = oReplaceValue.text() if oSearchCase.checkState() = Qt_Unchecked # 英数大小文字非同一視 cStr = SubStr(cStr,cOldValue,cNewValue,true) else # 英数大小文字同一視 cStr = SubStr(cStr,cOldValue,cNewValue) ok textedit1.setText(cStr) new qMessagebox(oSearch) { SetWindowTitle("Replace All") SetText("Operation Done") show() } Func pSearchClose oSearch.close() oSearch = NULL func pSearchKeyPress if oSearchFilter.getKeyCode() = Qt_Key_Escape pSearchClose() ok func pFindValue oCursor = textedit1.textcursor() nPosStart = oCursor.Position() + 1 cValue = oSearchValue.text() cStr = textedit1.toplaintext() cStr = substr(cStr,nPosStart) if oSearchCase.checkState() = Qt_Unchecked cStr = lower(cStr) cValue = lower(cValue) ok nPos = substr(cStr,cValue) if nPos > 0 nPos += nPosStart - 2 oCursor = textedit1.textcursor() oCursor.setposition(nPos,0) textedit1.settextcursor(oCursor) oCursor = textedit1.textcursor() oCursor.setposition(nPos+len(cValue),1) textedit1.settextcursor(oCursor) return true else new qMessagebox(oSearch) { SetWindowTitle("Search") SetText("Cannot find :" + cValue) show() } return false ok func pNofileopened New qMessageBox(win1) { setWindowTitle("Sorry") setText("Save the file first!") show() } func pDebug if cActiveFileName = Null return pNofileopened() ok cCode = "start run " + cActiveFileName + nl system(cCode) func pRun if cActiveFileName = Null return pNofileopened() ok cCode = "start ring " + cActiveFileName + nl system(cCode) func pRunNoConsole if cActiveFileName = Null return pNofileopened() ok cCode = "start /b ring " + cActiveFileName + nl system(cCode) func pSave if cActiveFileName = NULL return pSaveAs() ok writefile(cActiveFileName,textedit1.toplaintext()) status1.showmessage("File : " + cActiveFileName + " saved!",0) lAskToSave = false func pSaveAs new qfiledialog(win1) { cName = getsavefilename(win1,"Save As","","source files(*.ring)") if cName != NULL cActiveFileName = cName writefile(cActiveFileName,textedit1.toplaintext()) status1.showmessage("File : " + cActiveFileName + " saved!",0) pSetActiveFileName() lAskToSave = false ok } func pPrint status1.showmessage("Printing to File : RingDoc.pdf",0) printer1 = new qPrinter(0) { setoutputformat(1) # 1 = pdf setoutputfilename("RingDoc.pdf") textedit1.print(printer1) } status1.showmessage("Done!",0) system("RingDoc.pdf") func pCut textedit1.cut() status1.showmessage("Cut!",0) func pCopy textedit1.copy() status1.showmessage("Copy!",0) func pPaste textedit1.paste() status1.showmessage("Paste!",0) func pFont oFontDialog = new qfontdialog() { aFont = getfont() } textedit1.selectall() cFont = aFont[1] pSetFont() Func pSetFont myfont = new qfont("",0,0,0) myfont.fromstring(cFont) textedit1.setcurrentfont(myfont) Func pColor new qcolordialog() { aTextColor = GetColor() } pSetColors() Func pColor2 new qcolordialog() { aBackColor = GetColor() } pSetColors() Func pSetColors textedit1.setstylesheet("color: rgb(" + aTextColor[1] + "," + aTextColor[2] + "," + aTextColor[3] + ");" + "background-color: rgb(" + aBackColor[1] + "," + aBackColor[2] + "," + aBackColor[3] + ")") func pOpen new qfiledialog(win1) { cName = getopenfilename(win1,"open file","c:\","source files(*.ring)") if cName != NULL cActiveFileName = cName textedit1.settext(read(cActiveFileName)) ok } func pNew new qfiledialog(win1) { cName = getsavefilename(win1,"New file","","source files(*.ring)") if cName != NULL write(cName,"") cActiveFileName = cName textedit1.settext(read(cActiveFileName)) ok } Func WriteFile cFileName,cCode aCode = str2list(cCode) fp = fopen(cFileName,"wb") for cLine in aCode fwrite(fp,cLine+char(13)+char(10)) next fclose(fp) Func MsgBox cTitle,cMessage new qMessagebox(win1) { setwindowtitle(cTitle) setText(cMessage) show() } Func pLang MsgBox("Programming Language", "This application developed using the Ring programming language") Func pGUI MsgBox("GUI Library", "This application uses the Qt GUI Library through RingQt") Func pAbout MsgBox("About", "2016, Mahmoud Fayed ") Func pSaveSettings cSettings = "aTextColor = ["+aTextColor[1]+","+aTextColor[2]+ ","+aTextColor[3]+"]" + nl + "aBackColor = ["+aBackColor[1]+","+aBackColor[2]+ ","+aBackColor[3]+"]" + nl + "cFont = '" + cFont + "'" + nl + "cWebSite = '" + cWebsite + "'" + nl cSettings = substr(cSettings,nl,char(13)+char(10)) write("ringnotepad.ini",cSettings) if lAsktoSave new qmessagebox(win1) { setwindowtitle("Save Changes?") settext("Some changes are not saved!") setInformativeText("Do you want to save your changes?") setstandardbuttons(QMessageBox_Yes | QMessageBox_No | QMessageBox_Cancel) result = exec() win1 { if result = QMessageBox_Yes pSave() but result = QMessageBox_Cancel return false ok } } ok return true Func pSetWebsite oWebView { loadpage(new qurl(cWebSite)) } oWBText { setText(cWebSite) } Func RestoreSettings eval(read("ringnotepad.ini")) pSetColors() pSetFont() pSetWebsite() Func pQuit if pSaveSettings() myapp.quit() ok 実行中のアプリケーション このスクリーンショットは “ファイル” メニューのデモです。 .. image:: ringqt_shot50.jpg :alt: Ring ノートパッド - ファイルメニュー このウィンドウは “検索と置換”です。 .. image:: ringqt_shot51.jpg :alt: Ring ノートパッド - 検索と置換 このスクリーンショットはアプリケーションのメインウィンドウのデモです。 .. image:: ringqt_shot49.jpg :alt: Ring ノートパッド - メインウィンドウ .. note:: 前述のサンプルにある pDebug(), pRun() および pRunNoConsole() 関数は移植性がありません! このサンプルでは MS-Windows 用に記述されており、ほかのオペレーティングシステム用に更新できます。 .. index:: pair: RingQt によるデスクトップとモバイル開発; Cards ゲーム Cards ゲーム ============ この用例は、 RingQt で開発したシンプルなカードゲームです。 各プレイヤーは五枚のカードを取得しますが、カードの中身は誰にもわかりません。 プレイヤーは毎回カードを確認するためにカードを一枚クリックします。 カードが別のカードと同じ番号ならば各カードのポイントを取得します。 カードの番号が “5” ならば、すべての可視状態のカードのポイントを取得します。 .. code-block:: ring Load "guilib.ring" nScale = 1 app1 = new qApp mypic = new QPixmap("cards.jpg") mypic2 = mypic.copy(0,(124*4)+1,79,124) Player1EatPic = mypic.copy(80,(124*4)+1,79,124) Player2EatPic= mypic.copy(160,(124*4)+1,79,124) aMyCards = [] aMyValues = [] for x1 = 0 to 3 for y1 = 0 to 12 temppic = mypic.copy((79*y1)+1,(124*x1)+1,79,124) aMyCards + temppic aMyValues + (y1+1) next next nPlayer1Score = 0 nPlayer2Score=0 do Page1 = new Game Page1.Start() again Page1.lnewgame mypic.delete() mypic2.delete() Player1EatPic.delete() Player2EatPic.delete() for t in aMyCards t.delete() next func gui_setbtnpixmap pBtn,pPixmap pBtn { setIcon(new qicon(pPixmap.scaled(width(),height(),0,0))) setIconSize(new QSize(width(),height())) } Class Game nCardsCount = 10 win1 layout1 label1 label2 layout2 layout3 aBtns aBtns2 aCards nRole=1 aStatus = list(nCardsCount) aStatus2 = aStatus aValues aStatusValues = aStatus aStatusValues2 = aStatus Player1EatPic Player2EatPic lnewgame = false nDelayEat = 0.5 nDelayNewGame = 1 func start win1 = new qWidget() { setwindowtitle("Five") setstylesheet("background-color: White") showfullscreen() } layout1 = new qvboxlayout() label1 = new qlabel(win1) { settext("Player (1) - Score : " + nPlayer1Score) setalignment(Qt_AlignHCenter | Qt_AlignVCenter) setstylesheet("color: White; background-color: Purple; font-size:20pt") setfixedheight(200) } closebtn = new qpushbutton(win1) { settext("Close Application") setstylesheet("font-size: 18px ; color : white ; background-color: black ;") setclickevent("Page1.win1.close()") } aCards = aMyCards aValues = aMyValues layout2 = new qhboxlayout() aBtns = [] for x = 1 to nCardsCount aBtns + new qpushbutton(win1) aBtns[x].setfixedwidth(79*nScale) aBtns[x].setfixedheight(124*nScale) gui_setbtnpixmap(aBtns[x],mypic2) layout2.addwidget(aBtns[x]) aBtns[x].setclickevent("Page1.Player1click("+x+")") next layout1.addwidget(label1) layout1.addlayout(layout2) label2 = new qlabel(win1) { settext("Player (2) - Score : " + nPlayer2Score) setalignment(Qt_AlignHCenter | Qt_AlignVCenter) setstylesheet("color: white; background-color: red; font-size:20pt") setfixedheight(200) } layout3 = new qhboxlayout() aBtns2 = [] for x = 1 to nCardsCount aBtns2 + new qpushbutton(win1) aBtns2[x].setfixedwidth(79*nScale) aBtns2[x].setfixedheight(124*nScale) gui_setbtnpixmap(aBtns2[x],mypic2) layout3.addwidget(aBtns2[x]) aBtns2[x].setclickevent("Page1.Player2click("+x+")") next layout1.addwidget(label2) layout1.addlayout(layout3) layout1.addwidget(closebtn) win1.setlayout(layout1) app1.exec() Func Player1Click x if nRole = 1 and aStatus[x] = 0 nPos = ((random(100)+clock())%(len(aCards)-1)) + 1 gui_setbtnpixmap(aBtns[x],aCards[nPos]) del(aCards,nPos) nRole = 2 aStatus[x] = 1 aStatusValues[x] = aValues[nPos] del(aValues,nPos) Player1Eat(x,aStatusValues[x]) checknewgame() ok Func Player2Click x if nRole = 2 and aStatus2[x] = 0 nPos = ((random(100)+clock())%(len(aCards)-1)) + 1 gui_setbtnpixmap(aBtns2[x],aCards[nPos]) del(aCards,nPos) nRole = 1 aStatus2[x] = 1 aStatusValues2[x] = aValues[nPos] del(aValues,nPos) Player2Eat(x,aStatusValues2[x]) checknewgame() ok Func Player1Eat nPos,nValue app1.processEvents() delay(nDelayEat) lEat = false for x = 1 to nCardsCount if aStatus2[x] = 1 and (aStatusValues2[x] = nValue or nValue=5) aStatus2[x] = 2 gui_setbtnpixmap(aBtns2[x],Player1EatPic) lEat = True nPlayer1Score++ ok if (x != nPos) and (aStatus[x] = 1) and (aStatusValues[x] = nValue or nValue=5) aStatus[x] = 2 gui_setbtnpixmap(aBtns[x],Player1EatPic) lEat = True nPlayer1Score++ ok next if lEat nPlayer1Score++ gui_setbtnpixmap(aBtns[nPos],Player1EatPic) aStatus[nPos] = 2 label1.settext("Player (1) - Score : " + nPlayer1Score) ok Func Player2Eat nPos,nValue app1.processEvents() delay(nDelayEat) lEat = false for x = 1 to nCardsCount if aStatus[x] = 1 and (aStatusValues[x] = nValue or nValue = 5) aStatus[x] = 2 gui_setbtnpixmap(aBtns[x],Player2EatPic) lEat = True nPlayer2Score++ ok if (x != nPos) and (aStatus2[x] = 1) and (aStatusValues2[x] = nValue or nValue=5 ) aStatus2[x] = 2 gui_setbtnpixmap(aBtns2[x],Player2EatPic) lEat = True nPlayer2Score++ ok next if lEat nPlayer2Score++ gui_setbtnpixmap(aBtns2[nPos],Player2EatPic) aStatus2[nPos] = 2 label2.settext("Player (2) - Score : " + nPlayer2Score) ok Func checknewgame if isnewgame() lnewgame = true if nPlayer1Score > nPlayer2Score label1.settext("Player (1) Wins!!!") ok if nPlayer2Score > nPlayer1Score label2.settext("Player (2) Wins!!!") ok app1.processEvents() delay(nDelayNewGame) win1.delete() app1.quit() ok Func isnewgame for t in aStatus if t = 0 return false ok next for t in aStatus2 if t = 0 return false ok next return true Func delay x nTime = x * 1000 oTest = new qTest oTest.qsleep(nTime) 実行中のアプリケーション .. image:: ringqt_shot48.jpg :alt: Cards ゲーム .. note:: 前述のスクリーンショットではプレイヤーが‘5’番のカードを入手していますがスコアは加算されていません。 これはほかのカードが不可視状態のときに‘5’番のカードを開いたからです! このスクリーンショットはモバイル機器 (Android) でゲームを実行しています。 .. image:: ringqt_shot52.jpg :alt: Cards ゲーム .. note:: Qt を使うと同じアプリケーションをほかのモバイルシステムで実行できます。 .. index:: pair: RingQt によるデスクトップとモバイル開発; クラスとメソッドでデフォルトのイベントを使うには クラスとメソッドでデフォルトのイベントを使うには ================================================ この表ではクラス名、およびメソッドで使用するデフォルトのイベントについて説明しています。 ============================== =========================================================== クラス名 メソッドで使用するデフォルトのイベント ============================== =========================================================== QPushButton SetClickEvent() QAction SetClickEvent() QLineEdit SetTextChangedEvent() .. SetCursorPositionChangedEvent() .. SetEditingFinishedEvent() .. SetReturnPressedEvent() .. SetSelectionChangedEvent() .. SetTextEditedEvent() QTextEdit SetCopyAvailableEvent() .. SetCurrentCharFormatChangedEvent() .. SetCursorPositionChangedEvent() .. SetRedoAvailableEvent() .. SetSelectionChangedEvent() .. SetTextChangedEvent() .. SetUndoAvailableEvent() QListWidget SetCurrentItemChangedEvent() .. SetCurrentRowChangedEvent() .. SetCurrentTextChangedEvent() .. SetItemActivatedEvent() .. SetItemChangedEvent() .. SetItemClickedEvent() .. SetItemDoubleClickedEvent() .. SetItemEnteredEvent() .. SetItemPressedEvent() .. SetItemSelectionChangedEvent() QTreeView SetCollapseEvent() .. SetExpandedEvent() .. SetActivatedEvent() .. SetClickedEvent() .. SetDoubleClickedEvent() .. SetEnteredEvent() .. SetPressedEvent() .. SetViewportEnteredEvent() QTreeWidget SetCollapsedEvent() .. SetExpandedEvent() .. SetActivatedEvent() .. SetClickedEvent() .. SetDoubleClickedEvent() .. SetEnteredEvent() .. SetPressedEvent() .. SetViewportEnteredEvent() .. SetCurrentItemChangedEvent() .. SetItemActivatedEvent() .. SetItemChangedEvent() .. SetItemClickedEvent() .. SetItemCollapsedEvent() .. SetItemDoubleClickedEvent() .. SetItemEnteredEvent() .. SetItemExpandedEvent() .. SetItemPressedEvent() .. SetItemSelectionChangedEvent() QComboBox SetActivatedEvent() .. SetCurrentIndexChangedEvent() .. SetEditTextChangedEvent() .. SetHighlightedEvent() QTabWidget SetCurrentChangedEvent() .. SetTabCloseRequestedEvent() QTableWidget SetCellActivatedEvent() .. SetCellChangedEvent() .. SetCellClickedEvent() .. SetCellDoubleClickedEvent() .. SetCellEnteredEvent() .. SetCellPressedEvent() .. SetCurrentCellChangedEvent() .. SetCurrentItemChangedEvent() .. SetItemActivatedEvent() .. SetItemChangedEvent() .. SetItemClickedEvent() .. SetItemDoubleClickedEvent() .. SetItemEnteredEvent() .. SetItemPressedEvent() .. SetItemSelectionChangedEvent() QProgressBar SetValueChangedEvent() QSpinBox SetValueChangedEvent() QSlider SetActionTriggeredEvent() .. SetRangeChangedEvent() .. SetSliderMovedEvent() .. SetSliderPressedEvent() .. SetSliderReleasedEvent() .. SetValueChangedEvent() QDial SetActionTriggeredEvent() .. SetRangeChangedEvent() .. SetSliderMovedEvent() .. SetSliderPressedEvent() .. SetSliderReleasedEvent() .. SetValueChangedEvent() QWebView SetLoadFinishedEvent() .. SetLoadProgressEvent() .. SetLoadStartedEvent() .. SetSelectionChangedEvent() .. SetTitleChangedEvent() .. SetUrlChangedEvent() QCheckBox SetStateChangedEvent() .. SetClickedEvent() .. SetPressedEvent() .. SetReleasedEvent() .. SetToggledEvent() QRadioButton SetClickedEvent() .. SetPressedEvent() .. SetReleasedEvent() .. SetToggledEvent() QButtonGroup SetButtonClickedEvent() .. SetButtonPressedEvent() .. SetButtonReleasedEvent() QVideoWidget SetBrightnessChangedEvent() .. SetContrastChangedEvent() .. SetFullScreenChangedEvent() .. SetHueChangedEvent() .. SetSaturationChangedEvent() QTimer SetTimeoutEvent() QTcpServer SetAcceptErrorEvent() .. SetNewConnectionEvent() QIODevice SetAboutToCloseEvent() .. SetBytesWrittenEvent() .. SetReadChannelFinishedEvent() .. SetReadyReadEvent() QAbstractSocket SetConnectedEvent() .. SetDisconnectedEvent() .. SetErrorEvent() .. SetHostFoundEvent() .. SetProxyAuthenticationRequiredEvent() .. SetStateChangedEvent() QTcpSocket SetConnectedEvent() .. SetDisconnectedEvent() .. SetErrorEvent() .. SetHostFoundEvent() .. SetProxyAuthenticationRequiredEvent() .. SetStateChangedEvent() .. SetAboutToCloseEvent() .. SetBytesWrittenEvent() .. SetReadChannelFinishedEvent() .. SetReadyReadEvent() QColorDialog SetColorSelectedEvent() .. SetCurrentColorChangedEvent() QNetworkAccessManager SetFinishedEvent() QThread SetStartedEvent() .. SetFinishedEvent() ============================== =========================================================== .. index:: pair: RingQt によるデスクトップとモバイル開発; イベントでイベントフィルタによるメソッド イベントでイベントフィルタによるメソッド ============================================ RingQt はイベントフィルタを使用することにより、新しいクラス QAllEvents を定義しています。 この表は利用可能なメソッドです。 ================================ ====================== メソッドで取得する仮引数 クラス名 ================================ ====================== getKeyCode() --> Number QAllEvents getx() --> Number gety() --> Number getglobalx() --> Number getglobaly() --> Number getbutton() --> Number getbuttons() --> Number ================================ ====================== この表はイベントで使用するメソッドを解説しています。 =================================================== ====================== メソッド名 クラス名 =================================================== ====================== setKeyPressEvent(cEvent) QAllEvents setMouseButtonPressEvent(cEvent) setMouseButtonReleaseEvent(cEvent) setMouseButtonDblClickEvent(cEvent) setMouseMoveEvent(cEvent) setCloseEvent(cEvent) setContextMenuEvent(cEvent) setDragEnterEvent(cEvent) setDragLeaveEvent(cEvent) setDragMoveEvent(cEvent) setDropEvent(cEvent) setEnterEvent(cEvent) setFocusInEvent(cEvent) setFocusOutEvent(cEvent) setKeyReleaseEvent(cEvent) setLeaveEvent(cEvent) setNonClientAreaMouseButtonDblClickEvent(cEvent) setNonClientAreaMouseButtonPressEvent(cEvent) setNonClientAreaMouseButtonReleaseEvent(cEvent) setNonClientAreaMouseMoveEvent(cEvent) setMoveEvent(cEvent) setResizeEvent(cEvent) setWindowActivateEvent(cEvent) setWindowBlockedEvent(cEvent) setWindowDeactivateEvent(cEvent) setWindowStateChangeEvent(cEvent) setWindowUnblockedEvent(cEvent) =================================================== ====================== .. index:: pair: RingQt によるデスクトップとモバイル開発; Qt と RingQt の違い Qt と RingQt の違い =================== (1) RingQt ではイベントの実行用コードを設定するために単純なメソッドを使用します。 文法: .. code-block:: none SetEvent(cEventCode) (2) RingQt では Ring キーワードとの衝突を回避するためにメソッド名を変更しています。 この表は変更点の解説です。 =============================== ====================== ===================== クラス名 Qt メソッド名 RingQt メソッド名 =============================== ====================== ===================== QWebView load loadpage QMediaPlaylist load loadfile QMediaPlaylist next movenext QPainter end endpaint QPicture load loadfile QLineEdit end endtext QDialog done donedialog QTextDocument end enddoc QTextBlock next nextblock QSqlQuery next movenext QImage load loadimage QNetworkAccessManager get getvalue QNetworkAccessManager put putvalue QThread exit exitfromthread QRegularExpressionMatchIterator next nextitem QCamera load loadcamera =============================== ====================== ===================== .. index:: pair: RingQt によるデスクトップとモバイル開発; RingQt クラスおよび Qt の取扱説明書 RingQt クラスおよび Qt の取扱説明書 ========================================= Qt 取扱説明書 : http://doc.qt.io/qt-5/classes.html 対応しているクラスとメソッドについては “RingQt クラスとメソッドのリファレンス” の章を参照してください。 .. index:: pair: RingQt によるデスクトップとモバイル開発; 新しいクラス名 - 1 からインデックスを開始 新しいクラス名 - 1 からインデックスを開始 ========================================= RingQt には新しいクラスが追加されています - 別バージョンのクラス名は小文字 “q” で開始されません。 また GUI コントロールなど扱うときにインデックスが 1 から開始するようにメソッドを更新してあります。 * ComboBox * ListWidget * TableWidget * TreeWidget 前述のクラスは guilib.ring の System.GUI パッケージに実装されています: 用法 .. code-block:: ring load "guilib.ring" import System.GUI これは以前のコードに一切影響を与えません。 つまり Ring の規則と整合性がある優れたコードへの第三の選択です。 またフォームデザイナーは、クラス間で「インデックスを 0 から開始」 または「インデックスを 1 から開始」を選択肢を使用するために更新しました。 用例 (フォームデザイナーを使用) (1) https://github.com/ring-lang/ring/blob/master/applications/formdesigner/tests/indexstart/indexstartView.ring (2) https://github.com/ring-lang/ring/blob/master/applications/formdesigner/tests/indexstart/indexstartController.ring .. index:: pair: RingQt によるデスクトップとモバイル開発; WebLib および GUILib によるレポートの作成方法 WebLib および GUILib によるレポートの作成方法 ================================================= WebLib には HtmlPage クラスがあります。 このクラスにより WebLib と GUILib で手軽にレポートを作成できます。 用例: .. code-block:: ring load "stdlib.ring" load "weblib.ring" load "guilib.ring" import System.Web import System.GUI new qApp { open_window(:CustomersReportController) exec() } class CustomersReportController oView = new CustomersReportView func Start CreateReport() func CreateReport mypage = new HtmlPage { h1 { text("Customers Report") } Table { style = stylewidth("100%") + stylegradient(4) TR { TD { WIDTH="10%" text("Customers Count : " ) } TD { text (100) } } } Table { style = stylewidth("100%") + stylegradient(26) TR { style = stylewidth("100%") + stylegradient(24) TD { text("Name " ) } TD { text("Age" ) } TD { text("Country" ) } TD { text("Job" ) } TD { text("Company" ) } } for x = 1 to 100 TR { TD { text("Test" ) } TD { text("30" ) } TD { text("Egypt" ) } TD { text("Sales" ) } TD { text("Future" ) } } next } } write("report.html",mypage.output()) func PrintEvent printer1 = new qPrinter(0) { setoutputformat(1) setoutputfilename("report.pdf") } oView { web.print(printer1) web.show() } system ("report.pdf") class CustomersReportView win = new window() { setwindowtitle("Report Window") setgeometry(100,100,500,500) web = new webview(win) { setgeometry(100,100,1000,500) loadpage(new qurl("file:///"+ currentdir()+"/report.html")) } new pushbutton(win) { setGeometry(100,20,100,30) settext("Print") setclickevent(Method(:PrintEvent)) } showMaximized() } スクリーンショット: .. image:: ring15reportshot.png :alt: 顧客報告書