0
点赞
收藏
分享

微信扫一扫

ImagePy的起手式IPy.py代码解析


这里主要对ImagePy中一个IPy.py进行难点讲解。

让我们好好学习Python高手的代码吧。


源码在此

​​

​​

​​


推荐大神写的IPy解析文章

ImagePy解析:8 -- 由新建图像谈起(引出IPy、ImagePlus、Canvas、ImageManager)qixinbo.info

ImagePy的起手式IPy.py代码解析_图像处理




下面是难点讲解:

from pubsub import pub

pub模块支持:

消息传递:发布和接收给定主题的消息

跟踪:跟踪应用程序中的pubsub活动

捕获异常:处理“表现糟糕的”侦听器(即泄漏异常)

主题树的规范:定义(或仅仅记录)应用程序的主题树;消息数据规范(MDS)

pubsub.js消息的发布订阅

// 导入 import PubSub from "pubsub-js" // 在有数据的地方进行发布 class Data extends React.Component{ pubmsg = ()=>{ PubSub.publish("频道","频道发布的消息") } render() { return( <button onClick={this.pubmsg}>Data组件,发布消息</button> ) } } // 订阅 class App extends Component { // 组件将要被渲染的时候进行订阅 componentWillMount() { PubSub.subscribe("频道", (msg,data)=> { console.log(msg,data) }) } render() { return ( <div className="App"> <Data /> </div> ); } }

参考原文链接:​​https://wxpython.org/Phoenix/docs/html/wx.lib.pubsub.pub.html​​

​​pubsub.js消息的发布订阅​​

root_dir = osp.abspath(osp.dirname(__file__))

os.path.dirname(path)

语法:os.path.dirname(path)

功能:去掉文件名,返回目录

如:

print(os.path.dirname("E:/Read_File/read_yaml.py")) #结果: E:/Read_File

print(os.path.dirname("E:/Read_File")) #结果: E:/

>>> import os >>> os.path.realpath(__file__) f:\work\tmp\test.py >>> os.path.abspath(__file__) f:\work\tmp\test.py

os.path.abspath() 和 os.path.realpath()不同点

example:

file_a

file_b -> file_a # 软连接指向a

>>> import os >>> os.path.abspath(file_b) /tmp/file_b # 会得到指向的文件的路径 >>> os.path.realpath(file_b) /tmp/file_a


extends = glob('plugins/*/menus')

glob模块用来查找文件目录和文件,常见的两个方法有glob.glob()和glob.iglob(),可以和常用的find功能进行类比,glob支持*?[]这三种通配符


  • *代表0个或多个字符
  • ?代表一个字符
  • []匹配指定范围内的字符,如[0-9]匹配数字

for xmlPath in glob.glob('/media/ai1/DATAPART11/LIDC-IDRI' +"/*"): # 解释:遍历指定文件夹下所有文件或文件夹

for xmlPath in glob.glob(xmlPath + "/*/*"): # 解释:遍历指定文件夹下的所有文件夹里的所有文件,/*/*可以根据文件夹层数自主设定

img_path = sorted(glob.glob(os.path.join(images, '*.npy'))) # 解释:遍历文件夹下所有npy文件


return manager.ConfigManager.get('uistyle') or 'ipy'

返回manager.ConfigManager.get('uistyle') or 'ipy'的布尔结果

(&,|)和(and,or)是两组比较相似的运算符

如果a,b是数值变量, 则&, |表示位运算, and,or则依据是否非0来决定输出,

如何a, b是逻辑变量, 则两类的用法基本一致

In[103]:(3>0) | (3<1) Out[103]: True In[104]:(3>0) and (3<1) Out[104]: False In[105]:(3>0) or (3<1) Out[105]: True In[106]:(3>0) & (3<1) Out[106]: False

# 判断变量是否为0, 是0则为False,非0判断为True, # and中含0,返回0; 均为非0时,返回后一个值, 2 and 0 # 返回0 2 and 1 # 返回1 1 and 2 # 返回2 # or中, 至少有一个非0时,返回第一个非0, 2 or 0 # 返回2 2 or 1 # 返回2 0 or 1 # 返回1

需要求得满足多个逻辑条件的数据时,要使用& 和|,在某些条件下用and/ or会报错‘ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().’

target_url = "http://aima.cs.berkeley.edu/data/iris.csv" data = pd.read_csv(target_url, header=None, columns=['s_line', 's_wid', 'p_line', 'p_wid', 'kind']) data.columns = ['s_line', 's_wid', 'p_line', 'p_wid', 'kind'] x_data = data.iloc[:, :-1] # 在多个逻辑条件下,用& 或者|, x_1 = x_data[x_data['s_line'] > 6 & x_data['p_wid'] > 0]


canvasp = CanvasPanel(curapp.canvasnb)

ImagePy风格的显示方式是以标签页的形式聚合显示不同图像,即传入CanvasPanel的是curapp.canvasnb,查看这个canvasnb即可知道,它是CanvasNoteBook类型的数据,其派生自wx.lib.agw.aui.AuiNotebook。 CanvasPanel又调用了同级目录canvas下的Canvas类,前面已经提到,该类已经从ImagePy中解耦,可以作为独立组件运行。 Canvas类的运行过程乍一看不好理解,其实它是利用了wxPython的SizeEvent:

self.bindEvents() def bindEvents(self): for event, handler in [ \ (wx.EVT_SIZE, self.on_size)]: self.Bind(event, handler)

即当窗口绘制时,就会调用on_size()函数,然后就会执行一系列的绘图等操作。

参考原文链接:​​ImagePy解析:8 -- 由新建图像谈起(引出IPy、ImagePlus、Canvas、ImageManager)​​


curapp.auimgr.Update()

ImagePy使用AuiManager来管理复杂界面

self.auimgr = aui.AuiManager() self.auimgr.SetManagedWindow( self )

Aui等于Advanced User Interface,它可以用来方便地管理多个面板,尤其是对于可停靠的(dockable)和可悬浮的(floating)的面板。

一个很好的关于AuiManager的教程见:

​​Day 4: wxPython AUI介绍​​

参考原文链接:​​ImagePy解析:4 -- 主界面渲染​​


elif uimode()=='ij':

换界面风格。

Andriod里面的夜间模式切换:

Mode 有四种类型可以选择:

MODE_NIGHT_NO: 使用亮色(light)主题,不使用夜间模式;

MODE_NIGHT_YES:使用暗色(dark)主题,使用夜间模式;

MODE_NIGHT_AUTO:根据当前时间自动切换 亮色(light)/暗色(dark)主题;

MODE_NIGHT_FOLLOW_SYSTEM(默认选项):设置为跟随系统,通常为 MODE_NIGHT_NO


public class AppConfig extends Application { @Override public void onCreate() { super.onCreate(); // 默认设置为日间模式 AppCompatDelegate.setDefaultNightMode( AppCompatDelegate.MODE_NIGHT_NO); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); initView(); } private void initView() { mChange = (Button) findViewById(R.id.change); mChange.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.change: // TODO 18/03/20 int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; getDelegate().setLocalNightMode(currentNightMode == Configuration.UI_MODE_NIGHT_NO ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO); // 同样需要调用recreate方法使之生效 recreate(); break; default: break; } }


wx.CallAfter(pub.sendMessage, 'showips', ips=ips)


wx.CallAfter(callable, *args, **kwargs)


其实这个方法也是利用PostEvent()来实现的。执行这个方法后,将在主事件循环中加入一个事件,然后通过事件循环进行处理。这其实是一种异步的方法,适用于一个非GUI的处理过程要调用GUI的方法,或子线程调用主线程的方法,或在一个事件处理函数中异步调用另一个事件处理,还有就是上面的问题。这个方法使用很方便,不需要自定义事件,绑定事件,Post事件。

应用bind功能与鼠标进行绑定,每次鼠标进入主界面的时候就会刷新,但是这样还不够完善。采用消息传递的方式,其实也是多线程里面的callafter和postevent。具体操作如下:

首先在子窗口的开头添加如下代码:

from wx.lib.pubsub import Publisher

from threading import Thread

然后在子窗口的结束函数出添加如下代码:

wx.CallAfter(Publisher().sendMessage,'update')

如果想批量创建一些按钮或者菜单键(我想这种事情是很普遍的),并且希望用同一个函数来处理它们,这个函数该怎样辨别是哪个按钮触发的事件呢?

下面这个例子就会建立一堆Menu的按键,并给他们编号,OnMenusClick就可以接收到它们的编号了:

menu=wx.Menu() for i in range(0,N): btn=menu.Append(wx.NewId(), str(i)) self.Bind(wx.EVT_MENU, lambda evt, mark=i : self.OnMenusClick(evt,mark) ,btn )

完成了!是不是感觉有点magic?关键在于这句

lambda evt, mark=i : self.OnMenusClick(evt,mark)

这句实际上产生了只接收evt一个参数的函数,并将其传递给了self.OnMenusClick,这样就能够实现给事件处理函数传递更多参数的目的了。

参考原文链接:​​[wxPython学习]wx.CallAfter和wx.FutureCall | 学步园​​

​​wxpython中bind怎么传递参数函数触发_百度知道​​


frame = VirturlCanvas(ImagePlus(imgs, title))

canvas上的虚拟画布。

画布上缩放

dc.SetUserScale

import wx class View(wx.Panel): def __init__(self, parent): super(View, self).__init__(parent) self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) self.Bind(wx.EVT_SIZE, self.on_size) self.Bind(wx.EVT_PAINT, self.on_paint) def on_size(self, event): event.Skip() self.Refresh() def on_paint(self, event): w, h = self.GetClientSize() dc = wx.AutoBufferedPaintDC(self) dc.Clear() dc.DrawLine(0, 0, w, h) dc.SetPen(wx.Pen(wx.BLACK, 5)) dc.DrawCircle(w / 2, h / 2, 100) class Frame(wx.Frame): def __init__(self): super(Frame, self).__init__(None) self.SetTitle('My Title') self.SetClientSize((500, 500)) self.Center() self.view = View(self) def main(): app = wx.App(False) frame = Frame() frame.Show() app.MainLoop() if __name__ == '__main__': main()

​​Best Canvas for WxPython​​

​​人类身份验证 - SegmentFault​​



举报

相关推荐

0 条评论