今朝の新聞の記事のタイトルである。
葛飾北斎の特別展が30日から大英博物館で始まる。北斎の「失われた作品」と言われた未公開作品100点余りが世界で初めて公開される。北斎の未出版の図鑑「万物絵本大全図」の下絵(版画になる前の絵)103点が中心となっている。
今朝の新聞の記事のタイトルである。
葛飾北斎の特別展が30日から大英博物館で始まる。北斎の「失われた作品」と言われた未公開作品100点余りが世界で初めて公開される。北斎の未出版の図鑑「万物絵本大全図」の下絵(版画になる前の絵)103点が中心となっている。
Pythonでマクロ:チェックボックス再論ではダイアログ上にチェックボックスを自動的に作成する問題を考えた。チェックボックスが多くなるとチェックボックスがダイアログ画面に納まらなくなる。(垂直)スクロールバーの出番である。
スクロールバーのモデルの詳細はここにある。
スクロールバーのツマミを動かすと
イヴェントが発生するがこのイヴェントの監視とイヴェント処理メッソド(adjustmentValueChanged
)の詳細はここにある。
チェックボックスは上図のようにダイアログ画面に納まらない縦長の紙に書かれていると想像してみる。このイヴェント処理メッソドではスクロールバーのツマミの位置の値(ScrollValue)を使ってこの縦長の紙の方を動かして紙のどの部分をダイアログ画面で見せるかを計算し個々のチェックボックスのダイアログ画面上の座標を変えてやる。
実行例の画像
スクロール・ツマミの動きに対してダイアログ画面をスムーズに変化させるにはスクロール属性LiveScrollをtrueにしておくとよい。
最後にマクロ本体を載せておく:
#coding: utf-8
import uno
import screen_io as ui
import unohelper
from com.sun.star.awt import XActionListener
from com.sun.star.awt import XAdjustmentListener
#「スクロールバー」の処理
class MyAdjustmentListener(unohelper.Base, XAdjustmentListener):
def __init__(self, dlgHgt, ckbxsHgt, ckbxs):
self.ckbxs = ckbxs
self.scrollVMax=100
self.dlgHgt=dlgHgt
self.ckbxsHgt=ckbxsHgt
self.ckbxPositionY0 = []
for ckbx in ckbxs:
print(ckbx.PositionY)
self.ckbxPositionY0.append(ckbx.PositionY)
def adjustmentValueChanged(self, event):
ratio = event.Value/self.scrollVMax
print(ratio)
for i,ckbx in enumerate(self.ckbxs):
ckbx.PositionY = self.ckbxPositionY0[i]-(self.ckbxsHgt - self.dlgHgt)*ratio
print( i, self.ckbxPositionY0[i], ckbx.PositionY)
#print(event.Type)
#print(event.Value)
#「完了」ボタンの処理
class FinishedListener(unohelper.Base, XActionListener):
def __init__(self, ckbxs, sheet):
self.ckbxs = ckbxs
self.sheet=sheet
def actionPerformed(self, evnt):
for i,ckbx in enumerate(self.ckbxs):
if(ckbx.State):
self.sheet.getCellByPosition(1, i+1 ).String = '○'
#ui.Print(ckbx.State)
#「リセット」ボタンの処理
class ResetListener(unohelper.Base, XActionListener):
def __init__(self, ckbxs):
self.ckbxs = ckbxs
def actionPerformed(self, evnt):
for ckbx in self.ckbxs:
ckbx.State=0
def python_macro_scbar(*arg):
#
#シート
doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.Sheets[0]
#データのある行数を調べる
sRange = sheet.getCellRangeByName("A1")
sCursor=sheet.createCursorByRange(sRange)
sCursor.collapseToCurrentRegion()
MaxDataRow = sCursor.Rows.Count-1
ui.Print(MaxDataRow)
items=[]
for i in range(MaxDataRow):
item = sheet.getCellByPosition(0, i+1 ).String
#ui.Print(item)
items.append(item)
#
#ダイアログ
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
dialogM = smgr.createInstance('com.sun.star.awt.UnoControlDialogModel')
# Size of DialogM
dlgWth = 150
dlgHgt = 150
dialogM.Width = dlgWth
dialogM.Height = dlgHgt
dialogM.Title = "選択ダイアログ"
#
#コントロールの作成・登録
#ラベル
lab1 = dialogM.createInstance('com.sun.star.awt.UnoControlFixedTextModel')
tabIndex = 0
lab1.Name = 'FixedLabel'
lab1.TabIndex = tabIndex
lab1.PositionX =0
lab1.PositionY =0
lab1.Width = dlgWth - 10
lab1.Height = 10
lab1.Label = "選択(複数)してください。"
lab1.Align = 1 # 0 : Left / 1 : Center / 2 : Right
lab1.Border = 0
lab1.TextColor = 0xff0000
lab1.Enabled = 1
dialogM.insertByName('FixedLabel', lab1)
#スクロールバー
scb1 = dialogM.createInstance('com.sun.star.awt.UnoControlScrollBarModel')
tabIndex += 1
scrollVMin=0
scrollVMax=100
scb1.Name = 'ScrollBar'
scb1.TabIndex = tabIndex
scb1.PositionX = dlgWth-10
scb1.PositionY = 0
scb1.Width = 10
scb1.Height = dlgHgt
scb1.Orientation=1
scb1.ScrollValueMin = scrollVMin
scb1.ScrollValueMax = scrollVMax
scb1.LiveScroll= 1
dialogM.insertByName('ScrollBar', scb1)
#ボタン
btn1 = dialogM.createInstance('com.sun.star.awt.UnoControlButtonModel')
tabIndex += 1
btn1.Name = 'OkBtn'
btn1.TabIndex = tabIndex
btn1.PositionX = dlgWth-50
btn1.PositionY = dlgHgt/2 - 20
btn1.Width = 32
btn1.Height = 10
btn1.Label = '完了'
btn1.PushButtonType = 0 # 1 : OK
dialogM.insertByName('OkBtn', btn1)
#
btn2 = dialogM.createInstance('com.sun.star.awt.UnoControlButtonModel')
tabIndex += 1
btn2.Name = 'ResetBtn'
btn2.TabIndex = tabIndex
btn2.PositionX = dlgWth-50
btn2.PositionY = dlgHgt/2 + 20
btn2.Width = 32
btn2.Height = 10
btn2.Label = 'リセット'
btn2.PushButtonType = 0 # 1 : OK
dialogM.insertByName('ResetBtn', btn2)
#チェックボックス
ckbxs=[]
for i in range(MaxDataRow):
ckbx = dialogM.createInstance('com.sun.star.awt.UnoControlCheckBoxModel')
tabIndex += 1
ckbxsHgt = 15+15*i+10
ckbx.Name = items[i]
ckbx.TabIndex = tabIndex
ckbx.PositionX = 10
ckbx.PositionY = ckbxsHgt
ckbx.Width = 100
ckbx.Height = 15
ckbx.Label = items[i]
# Dialog Modelの仕様に CheckBox Button1 の仕様を設定
dialogM.insertByName(items[i], ckbx)
ckbxs.append(ckbx)
#最終的なチェックボックス表の高さ
ckbxsHgt=ckbxsHgt+15
# Create the dialog and set the model
#ダイアログの生成とモデルの登録
dialog = smgr.createInstance('com.sun.star.awt.UnoControlDialog')
dialog.setModel(dialogM)
#コントロールの登録
cmdBtn1 = dialog.getControl('OkBtn')
cmdBtn2 = dialog.getControl('ResetBtn')
cmdScb1 = dialog.getControl('ScrollBar')
#エヴェント監視(ボタンが押されたとき)
btn1_listener = FinishedListener(ckbxs, sheet)
cmdBtn1.addActionListener(btn1_listener)
btn2_listener = ResetListener(ckbxs)
cmdBtn2.addActionListener(btn2_listener)
#エヴェント監視(スクロールバー)
scb1_listener = MyAdjustmentListener(dlgHgt, ckbxsHgt, ckbxs)
cmdScb1.addAdjustmentListener(scb1_listener)
#
#窓の生成そしてこの窓をダイアログ画面として使う
window = smgr.createInstance('com.sun.star.awt.Toolkit')
dialog.createPeer(window,None) # None : OK / none : NG
#
dialog.execute()
dialog.dispose()
アンケート調査のように多数の質問項目がありそれにチェックを入れるような状況を想定したLibreofficeのマクロをPythonで作る問題である。
以前にはチェック項目が少ないばあいのマクロを紹介した。チェック項目が多くなると手動でチェック欄を設定するが大変になる。
問題はこうだ:
画像のようにLibreofficeのCalcのシート上に多くのチェック項目が書かれているとする。これらにチェック欄を設定(フォームやダイアログ上のチェックボックス)することである。
ここでは
ダイアログのマクロでCalcシート上のチェック項目を読み込み必要な個数のチェックボックスをダイアログの中に自動的に作る。ユーザはこのチェックボックスに必要なチェックを入れ「完了」ボタンを押すとその結果がシートに反映される。「リセット」ボタンは全てのチェック欄のリセットに使う。
マクロの本体は長いので最後に載せた。このマクロはシート上のチェック項目の多寡に拘わらず使えるが、チェック項目は多くなったときにはチェックボックスがダイアログ画面をはみ出してしまう。ダイアログに縦スクロールを付けてダイアログ画面を制御できればよいわけであるがこれは未実装である。
【マクロ】
#coding: utf-8>
import uno
import screen_io as ui
import unohelper
from com.sun.star.awt import XActionListener
#「完了」ボタンの処理
class FinishedListener(unohelper.Base, XActionListener):
def __init__(self, ckbxs, sheet):
self.ckbxs = ckbxs
self.sheet=sheet
def actionPerformed(self, evnt):
for i,ckbx in enumerate(self.ckbxs):
if(ckbx.State):
self.sheet.getCellByPosition(1, i+1 ).String = '○'
#ui.Print(ckbx.State)
#「リセット」ボタンの処理
class ResetListener(unohelper.Base, XActionListener):
def __init__(self, ckbxs):
self.ckbxs = ckbxs
def actionPerformed(self, evnt):
for ckbx in self.ckbxs:
ckbx.State=0
def python_macro_ckbx(*arg):
#
#シート
doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.Sheets[0]
#データのある行数を調べる
sRange = sheet.getCellRangeByName("A1")
sCursor=sheet.createCursorByRange(sRange)
sCursor.collapseToCurrentRegion()
MaxDataRow = sCursor.Rows.Count-1
ui.Print(MaxDataRow)
items=[]
for i in range(MaxDataRow):
item = sheet.getCellByPosition(0, i+1 ).String
#ui.Print(item)
items.append(item)
#
#ダイアログ
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
dialogM = smgr.createInstance('com.sun.star.awt.UnoControlDialogModel')
# Size of DialogM
dlgWth = 150
dlgHgt = 200
dialogM.Width = dlgWth
dialogM.Height = dlgHgt
dialogM.Title = "選択ダイアログ"
#
#コントロールの作成・登録
#ラベル
lab1 = dialogM.createInstance('com.sun.star.awt.UnoControlFixedTextModel')
tabIndex = 0
lab1.Name = 'FixedLabel'
lab1.TabIndex = tabIndex
lab1.PositionX = 10
lab1.PositionY = 10
lab1.Width = 100
lab1.Height = 10
lab1.Label = "選択(複数)してください。"
lab1.Align = 1 # 0 : Left / 1 : Center / 2 : Right
lab1.Border = 0
lab1.TextColor = 0xff0000
lab1.Enabled = 1
dialogM.insertByName('FixedLabel', lab1)
#ボタン
btn1 = dialogM.createInstance('com.sun.star.awt.UnoControlButtonModel')
tabIndex += 1
btn1.Name = 'OkBtn'
btn1.TabIndex = tabIndex
btn1.PositionX = dlgWth-50
btn1.PositionY = dlgHgt/2 - 20
btn1.Width = 32
btn1.Height = 10
btn1.Label = '完了'
btn1.PushButtonType = 0 # 1 : OK
dialogM.insertByName('OkBtn', btn1)
#
btn2 = dialogM.createInstance('com.sun.star.awt.UnoControlButtonModel')
tabIndex += 1
btn2.Name = 'ResetBtn'
btn2.TabIndex = tabIndex
btn2.PositionX = dlgWth-50
btn2.PositionY = dlgHgt/2 + 20
btn2.Width = 32
btn2.Height = 10
btn2.Label = 'リセット'
btn2.PushButtonType = 0 # 1 : OK
dialogM.insertByName('ResetBtn', btn2)
#チェックボックス
ckbxs=[]
for i in range(MaxDataRow):
ckbx = dialogM.createInstance('com.sun.star.awt.UnoControlCheckBoxModel')
tabIndex += 1
ckbx.Name = items[i]
ckbx.TabIndex = tabIndex
ckbx.PositionX = 10
ckbx.PositionY = 15+15*i+10
ckbx.Width = 100
ckbx.Height = 15
ckbx.Label = items[i]
# Dialog Modelの仕様に CheckBox Button1 の仕様を設定
dialogM.insertByName(items[i], ckbx)
ckbxs.append(ckbx)
# Create the dialog and set the model
#ダイアログの生成とモデルの登録
dialog = smgr.createInstance('com.sun.star.awt.UnoControlDialog')
dialog.setModel(dialogM)
#コントロールの登録
cmdBtn1 = dialog.getControl('OkBtn')
cmdBtn2 = dialog.getControl('ResetBtn')
#エヴェント監視(ボタンが押されたとき)
btn1_listener = FinishedListener(ckbxs, sheet)
cmdBtn1.addActionListener(btn1_listener)
btn2_listener = ResetListener(ckbxs)
cmdBtn2.addActionListener(btn2_listener)
#
#窓の生成そしてこの窓をダイアログ画面として使う
window = smgr.createInstance('com.sun.star.awt.Toolkit')
dialog.createPeer(window,None) # None : OK / none : NG
#
dialog.execute()
dialog.dispose()
これも今朝の新聞の記事のタイトルである。
南米のチリが23日、核兵器禁止条約に批准した。これにより同条約に批准した国は56ヵ国となった。
今朝の新聞の記事のタイトルである。
メソポタミア文明を象徴するギルガメシュ叙事詩の粘土板が30年ぶりに郷土のイラクに帰還されたというニュースである。
この粘土板は元々イラクの博物館にあったものであるが、湾岸戦争のときに盗難にあった。幾多の変遷を経て米国ワシントンの博物館に持ち込まれた。
返還式ではイラクのフンマーディ文化相は「イラク社会に自尊心や自信を取り戻したに等しい」と語った。
このギルガメシュ叙事詩は紀元前1500年ごろのもので人類最古の文学と考えられている。
今日は仙台は快晴で、月がきれいに見えた。明日は「中秋の名月」の夜である。
「中秋の名月」は旧暦の8月15日に見る月のことである。これを「芋名月」と言ったする。旧暦の1日が新月でそれから15日たった月であるのでほぼ満月であるが必ずしも満月と一致するわけではない。
今年の「中秋の名月」は8年ぶりの満月の由。
旧暦の9月15日は「豆名月」である。
今朝の新聞の記事のタイトルである。欧州南天文台(ESO)は南米チリにある超大型望遠鏡(VLT)で小惑星クレオパトラ(地球から2億キロにある)の形を調べこの形は犬が大好きな骨のような形になっていることを明らかにした。
画像はここ。
櫛刺し団子(二個の)のようになっていて端から端まで270kmである。密度が低いことからクレオパトラは別の小惑星どうしの衝突でできた小物体が集合してできた可能性も示唆されている。
ASOP(Alternative Script Organizer for Python)をヴァージョン1.30にアップしたので改めてこのユーティリティーの使い方を纏めておく。
LibreOfficeのPythonでマクロを作るとき役に立つ。このユーティリティーはここで詳しく触れた。
【新規にマクロを作る作業】
LibreOfficeのCalcの「ツール」->「マクロ」->「Pythonスクリプトの管理」を選択する。ASOPの管理窓がでる。ライブラリー:マイマクロ内に新規にマクロを作るとする。管理窓のメニューから「モジュール作成」を選択し適当なモジュール名を入れる。そのモジュール名を選択してメニューから「編集」を選ぶとモジュールのテンプレートがエディター画面に現れる。その画面上でマクロを新規に作り文字コードutf-8で保存する。これで新規マクロが作成された。
このモジュール内に作られたマクロのASOP下でのデバックは以前に説明した。
今朝の新聞で気になった記事のタイトルである。
大学の「入学金」制度の見直しを求める運動「入学金納入時期延長を求める学生有志の会」の訴えである。
入学しない大学にも支払わないといけない「入学金」。これを問題としている。
会で調べてところ東京都内の私立大学の42%が入学金の納入期限を2月中に設定している。国立大学など3月に合格発表がある大学を第一志望にするばあい平均30万円と言われている「入学金」を入学するかどうかわからない大学にも支払わないということになる。
会ではまずこの入学金の納入期限の延長を求めている。そして根本的には入学金制度の仕組みそのものの見直しを求めている。
仙台の東北学院大学みると入学金は27万円で入学手続き時に支払うことになっている。入学手続きの期限は2月25日である。
ギリシア神話で有名なトロイア戦争。その発端が面白い。
ペーレウスとテティスの結婚披露宴に全ての神々が招待されたが「争いの女神」エリスは招待されなかった。怒った女神は一座の中に黄金のリンゴを投げ入れた。そのリンゴにには「いちばん美しい女神へ」と書いてあった。ヘーラー、アプロディーテー、アテーナーの三女神の間で争奪戦が起きた。ゼウスが仲裁に入り、羊飼いのパリスのその審判を任せることにした。
三女神はパリスを買収したが、「人間の中で一番美しい女性をパリスに与える」と約束したアプロディーテーがリンゴを得ることになった。パリスに与えられた女性がヘレネーで当時スパルタ王メネラーオスの妃であった。
「トロイ」という映画がある。神々は全く登場しないが結構面白い。