iuplua 简易记事本开发
iup版本:3.30 32位
lua版本:5.3.5 32位
自己根据官网教程写了一下,对iup的感觉就是麻雀虽小五脏俱全.在嵌入是上做些简单的功能还是可以的,不过估计嵌入式上一般都用qt.微型机上估计用iup的比较多.
稍微例举一下优点:
1.小巧,支持使用lua语言,调试的时候不用编译过,直接可以根据lua文件运行;
2.自带一些图标库,常用的一下事件都有封装;
给个链接,环境和代码都在里面:下载注:这个实例中还是有些功能可以完善,比如字符串查找只支持英文等问题,但是我这边时间有限就没有去深究了,如果以后要用iuplua做东西,再好好深入.
展示一下效果图:
require("iuplua")
require("iupluaimglib")
iup.SetGlobal("UTF8MODE","YES") --设置utf8编码方式
local M = {}
SimpleNotepad = M
--查找字符串
function fnFindString(str,str_to_find,casesensitive,start)
if not casesensitive then
return fnFindString(string.lower(str),string.lower(str_to_find),true,start)
end
return string.find(str,str_to_find,start,true)
end
-- 读文件
function fnReadFile(strFilePathName)
local iFile = io.open(strFilePathName,"r")
if not iFile then
iup.Message("错误","打开文件失败!" .. strFilePathName)
return nil
end
local strFileBuff = iFile:read("*a")
if not strFileBuff then
iup.Message("错误","读取文件失败!" .. strFilePathName)
return nil
end
iFile:close()
return strFileBuff
end
-- 写文件
function fnWriteFile(strFilePathName,strBuff)
local iFile = io.open(strFilePathName,"w")
if not iFile then
iup.Message("错误","打开文件失败!" .. strFilePathName)
return false
end
if nil ~= strBuff then
if not iFile:write(strBuff) then
iup.Message("错误","文件写入失败!" .. strFilePathName)
end
end
iFile:close()
return true
end
-- 视图变化处理函数
function fnViewChanged(item, bar)
if "ON" == item.value then
bar.floating = "YES" --设置浮动
bar.visible = "NO" --设置隐藏
item.value = "OFF"
else
bar.floating = "NO"
bar.visible = "YES"
item.value = "ON"
end
iup.Refresh(bar)
end
local m_config = iup.config{app_name = ".\\MainNotepad"} --路径:Windows C:\Users\UserName\MainNotepad.cfg
local m_tabMenu = {
item_new = iup.item{title="新建 \tCtrl+N",image="IUP_FileNew"},
item_open = iup.item{title="打开 \tCtrl+O",image="IUP_FileOpen"}, -- \t 文本右对齐 & 加下划线,
item_save = iup.item{title="保存 \tCtrl+S",image="IUP_FileSave"},
item_saveas = iup.item{title="另存为... \tCtrl+Shift+S"},
item_revert = iup.item{title="恢复"},
menu_recentFiles = iup.menu{}, -- 最近打开文件
item_exit = iup.item{title="退出"},
item_cut = iup.item{title="剪切 \tCtrl+X"},
item_copy = iup.item{title="复制 \tCtrl+C"},
item_paste = iup.item{title="粘贴 \tCtrl+V"},
item_delete = iup.item{title="删除 \tDel"},
item_find = iup.item{title="查找 \tCtrl+F"},
item_goto = iup.item{title="跳转 \tCtrl+G"},
item_select_all = iup.item{title="全选 \tCtrl+A"},
item_font = iup.item{title="字体..."},
item_toolbar = iup.item{title="工具栏视图...",value="ON"},
item_statusbar = iup.item{title="状态栏视图...",value="ON"},
item_help = iup.item{title="帮助..."},
item_about = iup.item{title="关于..."},
}
local m_tabToolButton = {
btn_new = iup.button{image="IUP_FileNew",flat = "Yes",canfocus = "No",tip = "打开(Ctrl+N)"},
btn_opne = iup.button{image = "IUP_FileOpen",flat = "Yes",canfocus = "No",tip = "打开(Ctrl+O)"}, -- flat 是否删除边框,canfocus 是否随着工具栏按钮的行为而获得键盘焦点
btn_save = iup.button{image = "IUP_FileSave",flat = "Yes",canfocus = "No",tip = "保存(Ctrl+S)"},
btn_cut = iup.button{image = "IUP_EditCut",flat = "Yes",canfocus = "No",tip = "剪切(Ctrl+X)"},
btn_copy = iup.button{image = "IUP_EditCopy",flat = "Yes",canfocus = "No",tip = "保存(Ctrl+C)"},
btn_paste = iup.button{image = "IUP_EditPaste",flat = "Yes",canfocus = "No",tip = "粘贴(Ctrl+V)"},
btn_find = iup.button{image = "IUP_EditFind",flat = "Yes",canfocus = "No",tip = "查找(Ctrl+F)"},
}
local m_multiText = iup.text{multiline = "YES",expand = "YES",config=m_config,dirty=nil}
local m_lblStatusbar = iup.label{title = "行 1,列 1",expand = "HORIZONTAL",padding = "10x5"}
local m_toolbarHBox = nil
function M:Main()
local fontConfig = initConfig()
if nil ~= fontConfig then
m_multiText.font = fontConfig
end
m_toolbarHBox = initToolbar()
--创建主窗口
local dlg = iup.dialog{
title = "SimpleNotepad 简单记事本",
size = "HALFxHALF",
menu = initMenu(),
iup.vbox{m_toolbarHBox,m_multiText,m_lblStatusbar},
close_cb = m_tabMenu.item_exit.action,
multitext=m_multiText,
dropfiles_cb=m_multiText.dropfiles_cb,
}
--快捷键
function dlg:k_any(c)
fnKeyAnyAction(c)
end
--显示
if nil ~= dlg then
iup.SetGlobal("PARENTDIALOG", iup.SetHandleName(dlg))
--dlg:showxy(iup.CENTER,iup.CENTER)
m_config:DialogShow(dlg,"MainWindow")
dlg.usersize = nil
iup.MainLoop()
iup.Close()
end
end
--设置文件标题
function fnSetFileTiltl(fileName)
local curFileName = string.gsub(fileName,"\\","/")
curFileName = string.reverse(curFileName)
local final = string.find(curFileName,'/')
curFileName = string.sub(curFileName,1,final - 1)
curFileName = string.reverse(curFileName)
return curFileName
end
--初始化配置
function initConfig()
m_config:Load()
local font = m_config:GetVariable("MainWindow","Font")
local toolbarFlag = m_config:GetVariable("MainWindow","Toolbar","ON")
local statusbarFlag = m_config:GetVariable("MainWindow","Statusbar","ON")
if "OFF" == toolbarFlag then
m_tabMenu.item_toolbar.value = toolbarFlag
m_toolbarHBox.floating = "YES"
m_toolbarHBox.visible = "NO"
end
if "OFF" == statusbarFlag then
m_tabMenu.item_statusbar.value = statusbarFlag
m_lblStatusbar.floating = "YES"
m_lblStatusbar.visible = "NO"
end
return font
end
--菜单栏初始化
function initMenu()
initMenuAction()
--文件
local file_menu = iup.menu{m_tabMenu.item_new,m_tabMenu.item_open,m_tabMenu.item_save,m_tabMenu.item_saveas,m_tabMenu.item_revert,
iup.separator{}, -- 分隔符
iup.submenu{title = "最近打开文件...",m_tabMenu.menu_recentFiles},m_tabMenu.item_exit}
--编辑
local edit_menu = iup.menu{m_tabMenu.item_cut,m_tabMenu.item_copy,m_tabMenu.item_paste,m_tabMenu.item_delete,iup.separator{},
m_tabMenu.item_find,m_tabMenu.item_goto,iup.separator{},
m_tabMenu.item_select_all}
--视图
local view_menu = iup.menu{m_tabMenu.item_toolbar,m_tabMenu.item_statusbar}
--文件相关回调
function file_menu:open_cb()
if m_multiText.dirty then
m_tabMenu.item_save.active = "YES"
else
m_tabMenu.item_save.active = "NO"
end
if m_multiText.dirty and m_multiText.filename then
m_tabMenu.item_revert.active = "YES"
else
m_tabMenu.item_revert.active = "NO"
end
end
--打开粘粘功能相关回调
function edit_menu:open_cb()
local clipboard = iup.clipboard{}
if not clipboard.textavailable then
m_tabMenu.item_paste.active = "NO" -- 不活动(置灰,不可选)
else
m_tabMenu.item_paste.active = "YES" -- 活动
end
if not m_multiText.selectedtext then
m_tabMenu.item_cut.active = "NO"
m_tabMenu.item_delete.active = "NO"
m_tabMenu.item_copy.active = "NO"
else
m_tabMenu.item_cut.active = "YES"
m_tabMenu.item_delete.active = "YES"
m_tabMenu.item_copy.active = "YES"
end
clipboard:destroy()
end
local sub_file = iup.submenu{file_menu,title = "文件"}
local sub_edit = iup.submenu{edit_menu,title = "编辑"}
local sub_format = iup.submenu{iup.menu{m_tabMenu.item_font},title = "格式"}
local sub_view = iup.submenu{view_menu,title="视图"}
local sub_help = iup.submenu{iup.menu{m_tabMenu.item_help,m_tabMenu.item_about},title = "帮助"}
--读取配置文件中打开目录
m_config:RecentInit(m_tabMenu.menu_recentFiles,10)
return iup.menu{sub_file,sub_edit,sub_format,sub_view,sub_help}
end
--菜单项点击事件绑定
function initMenuAction()
--新建文件
function m_tabMenu.item_new:action()
if fnSaveCheck(self) then
fnNewFile(self)
end
end
--打开文件
function m_tabMenu.item_open:action()
return fnOpenFile(self)
end
--保存
function m_tabMenu.item_save:action()
return fnSaveFile()
end
--另存为
function m_tabMenu.item_saveas:action()
return fnSaveAsFile()
end
--恢复
function m_tabMenu.item_revert:action()
fnOpenFileTom_multiText(self,m_multiText.filename)
end
--退出
function m_tabMenu.item_exit:action()
if fnSaveCheck(self) then
if 0 == string.len(m_multiText.value) or (nil == m_multiText.dirty) then
return iup.CLOSE
else
return iup.IGNORE
end
end
m_config:DialogClosed(iup.GetDialog(self), "MainWindow") --保存界面信息到配置文件
m_config:SetVariable("MainWindow","Font",m_multiText.font)
m_config:Save()
m_config:destroy()
return iup.CLOSE
end
--剪切
function m_tabMenu.item_cut:action()
iup.clipboard{text = m_multiText.selectedtext}
m_multiText.selectedtext = ""
iup.SetFocus(m_multiText)
end
--复制
function m_tabMenu.item_copy:action()
local clipboard = iup.clipboard{text = m_multiText.selectedtext}
clipboard:destroy()
end
--粘贴
function m_tabMenu.item_paste:action()
local clipboard = iup.clipboard{}
m_multiText.insert = clipboard.text
clipboard:destroy()
return iup.IGNORE
end
--删除
function m_tabMenu.item_delete:action()
m_multiText.selectedtext = ""
end
--查找字符串
function m_tabMenu.item_find:action()
fnFindStringAction(self)
end
--跳转
function m_tabMenu.item_goto:action()
fnGoToAction(self)
end
--全选
function m_tabMenu.item_select_all:action()
iup.SetFocus(m_multiText)
m_multiText.selection = "ALL"
end
--字体
function m_tabMenu.item_font:action()
local font = m_multiText.font
local fontDlg = iup.fontdlg{value = font}
fontDlg:popup(iup.CENTER,iup.CENTER)
if 1 == tonumber(fontDlg.status) then
m_multiText.font = fontDlg.value
end
fontDlg:destroy()
end
--工具栏菜单
function m_tabMenu.item_toolbar:action()
fnViewChanged(self,m_toolbarHBox)
m_config:SetVariable("MainWindow","Toolbar",self.value)
end
--状态栏菜单
function m_tabMenu.item_statusbar:action()
fnViewChanged(self,m_lblStatusbar)
m_config:SetVariable("MainWindow","Toolbar",self.value)
end
--帮助
function m_tabMenu.item_help:action()
iup.Help("https://www.baidu.com")
end
--关于
function m_tabMenu.item_about:action()
iup.Message("关于"," iup简单记事本\n 版本: B001")
end
end
--工具栏初始化
function initToolbar()
m_tabToolButton.btn_new.action = m_tabMenu.item_new.action
m_tabToolButton.btn_opne.action = m_tabMenu.item_open.action
m_tabToolButton.btn_save.action = m_tabMenu.item_save.action
m_tabToolButton.btn_cut.action = m_tabMenu.item_cut.action
m_tabToolButton.btn_copy.action = m_tabMenu.item_copy.action
m_tabToolButton.btn_paste.action = m_tabMenu.item_paste.action
m_tabToolButton.btn_find.action = m_tabMenu.item_find.action
local curHBox = iup.hbox{
m_tabToolButton.btn_new,
m_tabToolButton.btn_opne,
m_tabToolButton.btn_save,
iup.label{separator="VERTICAL"},
m_tabToolButton.btn_cut,
m_tabToolButton.btn_copy,
m_tabToolButton.btn_paste,
m_tabToolButton.btn_find,
margin = "4x4",
gap = 2
}
return curHBox
end
--新建文件
function fnNewFile(self)
local dlg = iup.GetDialog(self)
local multitext = dlg.multiText
dlg.title = "无标题 - 简易记事本"
multitext.filename = nil
multitext.dirty = nil
multitext.value = ""
end
--打开文件
function fnOpenFile(self)
local filedlg = iup.filedlg{
dialogtype = "OPEN",
filter = "*.txt",
--filterinfo = "文本文件(*.txt)",
extfilter = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*|",
}
filedlg:popup(iup.CENTER,iup.CENTER)
--获取返回值
if -1 ~= tonumber(filedlg.status) then
local openFilePath = filedlg.value
fnOpenFileToMultiText(self,openFilePath)
end
filedlg:destroy()
end
--保存,以前保存方式
function fnSaveFile()
print(m_multiText.filename)
if m_multiText.filename then
fnWriteFile(m_multiText.filename,m_multiText.value)
else
fnSaveAsFile()
end
end
--另存为,以前的另存为方法
function fnSaveAsFile()
local filedlg = iup.filedlg{
dialogtype = "SAVE",
filter = "*.txt",
filterinfo = "文本文件(*.txt)"
}
filedlg:popup(iup.CENTER,iup.CENTER)
--获取返回值
if -1 ~= tonumber(filedlg.status) then
if nil ~= m_multiText.value then
local openFilePath = filedlg.value
fnSaveAsFileToMultiText(m_multiText,openFilePath)
end
end
filedlg:destroy()
end
--打开文件
function fnOpenFileToMultiText(self,filename)
local str = fnReadFile(filename)
if str then
local dlg = iup.GetDialog(self)
local multiText = dlg.multiText
local config = multiText.config
dlg.title = fnSetFileTiltl(filename) .. "- 简易记事本"
multiText.filename = filename
multiText.dirty = nil
multiText.value = str
config:RecentUpdate(filename)
end
end
--保存
function fnSaveFileToMultiText(multiText)
if fnWriteFile(multiText.filename,multiText.value) then
multiText.dirty = nil
end
end
--另存为
function fnSaveAsFileToMultiText(multitext,filename)
if fnWriteFile(filename,multitext.value) then
local dlg = iup.GetDialog(multitext)
local config = multitext.config
dlg.title = fnSetFileTiltl(filename) .. "- 简易记事本"
multitext.filename = filename
multitext.dirty = nil
config:RecentUpdate(filename)
end
end
--保存校验
function fnSaveCheck(self)
local dlg = iup.GetDialog(self)
local multitext = dlg.multitext
if multitext.dirty then
local resp = iup.Alarm("警告","文件有改动是否保存?","Yes","No","Cancel")
if 1 == resp then
fnSaveFile()
multitext.dirty = nil
elseif 3 == resp then
return false
end
end
return true
end
--查找字符串处理
function fnFindStringAction(self)
local find_dlg = self.find_dialog
if not find_dlg then
local find_txt = iup.text{visiblecolumns = "30"}
local find_case = iup.toggle{title = "区分大小写"}
local bt_find_next = iup.button{title = "查找下一个",padding = "10x2"}
local bt_find_close = iup.button{title = "关闭",padding = "10x2"}
function bt_find_next:action()
local find_pos = tonumber(find_dlg.find_pos)
local str_to_find = find_txt.value
local casesensitive = ("NO" == find_case.value)
if (not str_to_find or 0 == str_to_find:len()) then
return nil
end
if not find_pos then
find_pos = 1
end
local str = m_multiText.value
local pos,end_pos = fnFindString(str,str_to_find,casesensitive,find_pos)
--没找到则从头找一次
if nil == pos then
pos,end_pos = fnFindString(str,str_to_find,casesensitive,1)
end
if pos and pos > 0 then
pos = pos - 1
find_dlg.find_pos = end_pos
iup.SetFocus(m_multiText)
m_multiText.selectionpos = pos .. ":" .. end_pos
local lin,col = iup.TextConvertPosToLinCol(m_multiText,pos) --根据位置,返回再第几行,第几列
local scrollPos = iup.TextConvertLinColToPos(m_multiText,lin,0) --根据行和列,返回滚动条位置
m_multiText.scrolltopos = scrollPos
else
find_dlg.find_pos = nil
iup.Message("警告","没有找到内容")
end
end
function bt_find_close:action()
iup.Hide(iup.GetDialog(self))
end
local vbox = iup.vbox{
iup.label{title = "查找字符串:"},
find_txt,
find_case,
iup.hbox{
iup.fill{}, -- 弹簧控件
bt_find_next,
bt_find_close,
normalizesize="HORIZONTAL",
},
margin = "10x10",
gap = "5"
}
find_dlg = iup.dialog{
vbox,
title = "查找",
dialogframe = "Yes",
defaultenter = bt_find_next, --默认enter键响应
defaultesc = bt_find_close, --默认esc键响应
parentdialog = iup.GetDialog(self) --设置父窗口
}
self.find_dialog = find_dlg
end
find_dlg:showxy(iup.CURRENT,iup.CURRENT) -- CURRENT表示在父窗口中居中显示,隐藏后再显示则重用上次的位置
end
--跳转处理
function fnGoToAction(self)
local line_count = m_multiText.linecount
local lbl_goto = iup.label{title = "行数 [1-"..line_count.."]:"}
local txt_goto = iup.text{mask = iup.MASK_UINT, visiblecolumns = 20}
local bt_goto_ok = iup.button{title = "OK", text_linecount = 0, padding = "10x2"}
bt_goto_ok.text_linecount = line_count
function bt_goto_ok:action()
local line_count = tonumber(self.text_linecount)
local line = tonumber(txt_goto.value)
if (line < 1 or line >= line_count) then
iup.Message("错误", "超出范围")
return
end
goto_dlg.status = 1
return iup.CLOSE
end
local bt_goto_cancel = iup.button{title = "取消", padding = "10x2"}
function bt_goto_cancel:action()
goto_dlg.status = 0
return iup.CLOSE
end
local box = iup.vbox{
lbl_goto,
txt_goto,
iup.hbox{
iup.fill{},
bt_goto_ok,
bt_goto_cancel,
normalizesize="HORIZONTAL",
},
margin = "10x10",
gap = "5",
}
goto_dlg = iup.dialog{
box,
title = "跳转",
dialogframe = "Yes",
defaultenter = bt_goto_ok,
defaultesc = bt_goto_cancel,
parentdialog = iup.GetDialog(self)
}
goto_dlg:popup(iup.CENTERPARENT, iup.CENTERPARENT)
if (tonumber(goto_dlg.status) == 1) then
local line = txt_goto.value
local pos = iup.TextConvertLinColToPos(m_multiText, line, 0)
m_multiText.caretpos = pos
m_multiText.scrolltopos = pos
end
goto_dlg:destroy()
end
--快捷键绑定
function fnKeyAnyAction(key)
-- iup.K_cX表示 Ctrl + X 其中X代表键
-- iup.K_sX表示 shift + X 其中X代表键
if key == iup.K_cN then
m_tabMenu.item_new:action()
elseif key == iup.K_cO then
m_tabMenu.item_open:action()
elseif key == iup.K_cS then
m_tabMenu.item_save:action()
elseif key == iup.XkeyShift(iup.XkeyCtrl(iup.K_S)) then -- 三键以上组合可以用此方法
m_tabMenu.item_saveas:action()
elseif key == iup.K_cF then
m_tabMenu.item_find:action()
elseif key == iup.K_cG then
m_tabMenu.item_goto:action()
end
end
--拖拽文件到程序回调
function m_multiText:dropfiles_cb(filename)
if fnSaveCheck(self) then
fnOpenFileToMultiText(self,filename)
end
end
--文本内容改变,改变状态
function m_multiText:valuechanged_cb()
self.dirty = "YES"
end
--主文本框光标位置改变回调函数,设置状态栏
function m_multiText:caret_cb(line,col)
m_lblStatusbar.title = "行 " .. line .. ",列 " .. col
end
--配置文件回调函数
function m_config:recent_cb()
local fileName = self.title
local strBuff = fnReadFile(fileName)
if strBuff then
m_multiText.value = strBuff
end
end
return SimpleNotepad