tag:crieit.net,2005:https://crieit.net/tags/%E5%85%A5%E9%96%80/feed 「入門」の記事 - Crieit Crieitでタグ「入門」に投稿された最近の記事 2021-09-26T19:54:52+09:00 https://crieit.net/tags/%E5%85%A5%E9%96%80/feed tag:crieit.net,2005:PublicArticle/17686 2021-09-26T19:49:37+09:00 2021-09-26T19:54:52+09:00 https://crieit.net/posts/aka-dicom-kiso1 これだけは知っておきたいDICOM <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>DICOMとは何ぞやとか成り立ちとかはおいておいて、DICOM勉強しはじめたときに手助けになるようなことを書いておく</p> <h1 id="お勉強用資料"><a href="#%E3%81%8A%E5%8B%89%E5%BC%B7%E7%94%A8%E8%B3%87%E6%96%99">お勉強用資料</a></h1> <h2><a target="_blank" rel="nofollow noopener" href="https://www.dclunie.com/dicom-status/status.html">DICOM Standard Status</a></h2> <p>最近は年間5回(a→b→c→d→e)更新される<br /> 現時点(2021年9月)で1~22章(9,13はリタイア)まであり、気が付いたら増えてたりする。<br /> よく見かけるPS3.Xという書き方のXは章番号を表している。ちなみに3の方はDICOMのVersionだが長らく変わっていない。</p> <p>とても全部は読めないのでおそらく大半の人が最初に必要になる、3~5章を眺めるといい。<br /> こんな情報が知りたいけどどこ見たらいいのかわからない場合は以下参考。</p> <div class="table-responsive"><table> <thead> <tr> <th>知りたいこと</th> <th>章番号</th> </tr> </thead> <tbody> <tr> <td>画像種・操作ごとに必要なタグが知りたい</td> <td>3章(情報オブジェクト定義)</td> </tr> <tr> <td>画像種・操作の組み合わせが知りたい</td> <td>4章(サービスクラス)</td> </tr> <tr> <td>VRの意味、DICOMデータの構造、バイナリデータの持ち方、文字コードの表し方、画像自体・輝度の計算が知りたい</td> <td>5章(データ構造と符号化)</td> </tr> <tr> <td>タグNo、タグ名、VR、VMが知りたい</td> <td>6章(データ辞書)</td> </tr> <tr> <td>DICOMメッセージのやり取りが知りたい</td> <td>7章(メッセージ交換)</td> </tr> <tr> <td>匿名化の対象や方法が知りたい</td> <td>15章(セキュリティ辞書)</td> </tr> <tr> <td>造影剤などコードとその意味の定義が知りたい</td> <td>16章(コンテンツマッピング)</td> </tr> </tbody> </table></div> <h2><a target="_blank" rel="nofollow noopener" href="https://www.jira-net.or.jp/dicom/index.html">JIRA DICOMの世界</a></h2> <p>DICOM規格の和訳(但し結構古いので注意)や、勉強会の資料などが置いてある。<br /> 「現場でDICOM接続に慌てないための知識」とか割と役立つので初心者は一度目を通しておくとよい。</p> <h1 id="DICOM通信はオブジェクト+サービスの組み合わせ"><a href="#DICOM%E9%80%9A%E4%BF%A1%E3%81%AF%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%EF%BC%8B%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B">DICOM通信はオブジェクト+サービスの組み合わせ</a></h1> <p>オブジェクトをどうする(サービス)かの組み合わせになる。まずはオブジェクトとサービス(クラス)の説明から。</p> <h2 id="オブジェクト(IOD=Information Object Definitions)"><a href="#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%28IOD%EF%BC%9DInformation+Object+Definitions%29">オブジェクト(IOD=Information Object Definitions)</a></h2> <p>要するに扱うもの。<br /> MR画像やCT画像といったもの。<br /> * MR Image IOD Modules<br /> * CT Image IOD Modules<br /> * Enhanced MR Image IOD Modules<br /> * SC Image IOD Modules</p> <p>など。<br /> Modulesと複数形になっている通り一つのオブジェクトを複数のモジュールで構成している。<br /> モジュールはまた複数のタグで構成されている。<br /> 例えばMR画像に関してはPS3.3のA4.3にモジュール群が書かれているが、各モジュールのReference列の節に飛ぶことで詳細なタグ情報がわかる。<br /> ※基本、DICOM規格読むときは飛びまくるので迷子にならないように注意すること。</p> <p>つまりこういう組み合わせ。<br /> <div class="table-responsive"><table> <thead> <tr> <th>IOD</th> <th>Module</th> <th>Tag</th> </tr> </thead> <tbody> <tr> <td>MR Image IOD Modules</td> <td>Patient</td> <td>Patient's Name(0010,0010)</td> </tr> <tr> <td></td> <td></td> <td>Patient ID(0010,0020)</td> </tr> <tr> <td></td> <td></td> <td>…</td> </tr> <tr> <td></td> <td>General Studies</td> <td>Study Instance UID(0020,000D)</td> </tr> <tr> <td></td> <td></td> <td>Study Date(0008,0020)</td> </tr> <tr> <td></td> <td></td> <td>…</td> </tr> <tr> <td></td> <td>…</td> <td>…</td> </tr> </tbody> </table></div></p> <p>ちなみにIODの表のUsage欄に書かれている記号はA1.3までさかのぼると書いてある。<br /> * Mandatory (see Section A.1.3.1), abbreviated M<br /> * Conditional (see Section A.1.3.2), abbreviated C<br /> * User Option (see Section A.1.3.3), abbreviated U</p> <p>こういうのもどこに書いてあるかわからなくなることが多々あるので、次に見つけたらメモしておこうと毎回思って忘れる。</p> <h2 id="サービスクラス"><a href="#%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%AF%E3%83%A9%E3%82%B9">サービスクラス</a></h2> <p>上記オブジェクトを「どうするか」の部分。<br /> 分かりやすいので言えば、「転送する」「印刷する」<br /> * Storage Management Service Ckass:転送する<br /> * Print Management Service Class:印刷<br /> * Modality Worklist Management Service Class(MWM):検査オーダ受信</p> <p>など。もっといっぱいあるが一個ずつ説明が重いので別で説明する、つもり。</p> <h2 id="オブジェクト+サービスの組み合わせ(SOP=Service Object Pair)"><a href="#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%2B%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%28SOP%3DService+Object+Pair%29">オブジェクト+サービスの組み合わせ(SOP=Service Object Pair)</a></h2> <p>オブジェクトとどうする(サービス)かの組み合わせのことをSOP Classと表す。<br /> SOP Class UID(0008,0016)はその組み合わせを示すユニークなIDとなり、通信時に必須となる。<br /> 要はこれからこういう通信を行うよ、と伝えるのにDICOM共通のIDがあると一発で伝えるため。<br /> SOP Instance UID(0008,0018)はあくまでインスタンスなので個別につける。但しUID=ユニークなIDなので1画像ずつ違うこと、上位の方はルールがあるので従う。それについてもそのうち書くかもしれない。</p> <h1 id="SCUとSCP"><a href="#SCU%E3%81%A8SCP">SCUとSCP</a></h1> <p>サービスを使いたい人とそれを提供する人。別の言い方をすればメッセージを投げる人と受け取る人。<br /> * SCU=Service Class User=サービスを使う人<br /> * SCP=Service Class Provider=サービスを提供する人</p> <p>Storage SCU(画像を送る人)、Storage SCP(画像を受け取る人)のように表される、慣れるまではどっちがどっちかよく忘れるのでわからなくなったら都度確認すること。</p> <div class="table-responsive"><table> <thead> <tr> <th>Service</th> <th>SCU</th> <th>SCP</th> </tr> </thead> <tbody> <tr> <td>Storage</td> <td>画像を転送したい(する)人(Modality)</td> <td>画像を受け取る人(PACS)</td> </tr> <tr> <td>Print</td> <td>画像を印刷したい人(Modality)</td> <td>画像を受け取り印刷する人(Printer)</td> </tr> <tr> <td>MWM</td> <td>検査オーダがないか知りたい人(Modality)</td> <td>検査オーダを返す人(RIS)</td> </tr> </tbody> </table></div> <h1 id="DICOM通信は3ステップ"><a href="#DICOM%E9%80%9A%E4%BF%A1%E3%81%AF3%E3%82%B9%E3%83%86%E3%83%83%E3%83%97">DICOM通信は3ステップ</a></h1> <p>DICOMの通信は大雑把に3ステップ</p> <ol> <li>アソシエーション確立(相互認証)</li> <li>データ通信(オブジェクト交換)</li> <li>アソシエーション解放(エラーの確認)</li> </ol> <p>当たり前だが、SCU側がアソシエーションを要求するところから始まる<br /> <div class="table-responsive"><table> <thead> <tr> <th>SCU</th> <th></th> <th>SCP</th> </tr> </thead> <tbody> <tr> <td>アソシエーション要求</td> <td>→</td> <td></td> </tr> <tr> <td></td> <td>←</td> <td>アソシエーション要求承諾</td> </tr> <tr> <td>データ送信(続きあるよ)</td> <td>→</td> <td></td> </tr> <tr> <td></td> <td>←</td> <td>データ受信</td> </tr> <tr> <td>データ送信(ここで終わり)</td> <td>→</td> <td></td> </tr> <tr> <td></td> <td>←</td> <td>データ受信</td> </tr> <tr> <td>アソシエーション解放要求</td> <td>→</td> <td></td> </tr> <tr> <td></td> <td>←</td> <td>アソシエーション解放要求承諾</td> </tr> </tbody> </table></div></p> <p>実際にはアソシエーション張る時にAEタイトルやAbstruct Syntax(SOP Class)、Transfer Syntax(ILE、ELE、JPEGLossyとか)確認する。<br /> データの送信中もC-STOREとかC-FINDとかそれぞれに応じたメッセージを使う。<br /> それはまた別で説明。</p> <h1 id="DICOMタグの構造"><a href="#DICOM%E3%82%BF%E3%82%B0%E3%81%AE%E6%A7%8B%E9%80%A0">DICOMタグの構造</a></h1> <p>患者名や検査日時、検査した結果の各種数値などなどはタグという形で保存されている。<br /> バイナリ的に見れば<br /> * TagNo<br /> * VR(Implicitだと省略)<br /> * Length<br /> * Value</p> <p>という構造になる。</p> <h2 id="データ構造"><a href="#%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0">データ構造</a></h2> <p>PS3.5の7.1を見ると色々書いてある。ILE,ELEとかパターン分けがあるが、簡単にだけ書いておくと<br /> * ILE=Implicit VR Little Endian:VRを省略する書き方(たぶん主流)<br /> * ELE=Explicit VR Little Endian:VRを明示的に書き出す書き方(メディア出力時とかはたまにこれの人がいる気がする)</p> <p>※Little EndianのあたりはDICOM関係ないから他所でどうぞ。ただEBEとかはRETIREしたからあまり考えなくていいかもしれない。</p> <p>要は<br /> TagNoがあって、VRがあるかないか、長さがあって、値がある<br /> というだけ。<br /> 知らないとわからないけど知ってればたいしたことはない。あとのVMとかSQタグとかでまた少し頭使うけど基本はこんな感じ。</p> <h2 id="TagNo"><a href="#TagNo">TagNo</a></h2> <p>TagNoの構造はGroupTagと呼ばれるうえ4桁、ElementTagと呼ばれる下4桁の計8桁の16進数で表される。GroupTag、ElementTagに従って(gggg,eeee)という書かれ方をすることもある。<br /> タグには大きく2種類あり、DICOM共通の標準タグ、標準タグで補えない情報がある場合に各団体が発行するプライベートタグ(PrivateTag)がある。</p> <p>標準タグもだいたいGroupでどんな内容が入っているか決まっていて<br /> <div class="table-responsive"><table> <thead> <tr> <th>GroupTag</th> <th>内容</th> </tr> </thead> <tbody> <tr> <td>0008</td> <td>検査情報</td> </tr> <tr> <td>0010</td> <td>患者情報</td> </tr> <tr> <td>0018</td> <td>画像収集情報</td> </tr> <tr> <td>0020</td> <td>画像付帯情報(たしか0018が多すぎてこっちに広がったと聞いた気がする)</td> </tr> <tr> <td>0028</td> <td>画像表示情報</td> </tr> <tr> <td>7FE0</td> <td>画素情報.(7FE0,0010)が画像のバイナリデータ</td> </tr> </tbody> </table></div></p> <p>※7FE0に関しては0008(Float)とか0009(Double Float)もあるけど使われてるのを知らない。</p> <h3 id="PrivateTag"><a href="#PrivateTag">PrivateTag</a></h3> <p>PrivateTagの見分けは簡単でGroupTagが奇数であること。逆に偶数であれば標準タグ。<br /> PrivateTagを発行した場合、必ず発行者を示すPrivateCreatorタグが必要となる。<br /> PrivateCreatorは(gggg,00ee)と決まっており、ElementTagの上位2桁は00と固定である。<br /> また、このPrivateCreatorが保証する範囲は(gggg,ee00-eeFF)までとなる。<br /> 具体例を挙げると</p> <pre><code>(0031,0033)="WATASHIDA" </code></pre> <p>が保証するのは</p> <pre><code>(0031,3300) (0031,3301) (0031,3302) … (0031,33FF) </code></pre> <p>までということ。PrivateCreatorのElement頭2桁が00なのもこれが理由。</p> <p>当たり前のことだけど独自のPrivateTagを出して、他所で使ってもらいたいならDICOM C/Sにちゃんと書いておくこと。</p> <h2 id="VR=Value Representation"><a href="#VR%3DValue+Representation">VR=Value Representation</a></h2> <p>そのタグの値が何で表されるか。<br /> 例えばSSならSigned Short、ULならUnsigned Long、STならShort Textといった具合に数値なら型が色々、文字列系なら長さや使用できる文字などの制限が様々、日付や時間、一部タグに特化したVRまで定義されているのでわからないうちはPS3.5の6.2の表を印刷して持っておくといい。</p> <h2 id="VM=Value Multiplicity"><a href="#VM%3DValue+Multiplicity">VM=Value Multiplicity</a></h2> <p>そのタグがいくつの値で構成されているか。<br /> 例えば患者の向きなどの情報の場合、3軸で表すのでVM=3。<br /> バイナリで見たときにVMを示す領域はないので、<br /> 数値のように固定長の場合、VRとLengthから割り出す。SS(2byte)でLengthが6ならVM=6/2=3。<br /> 文字列のような可変長の場合は、区切り文字"バックスラッシュ(\)[5CH]"が入るのでそこから割り出す。ImageType(0008,0008)が「ORIGINAL\PRIMARY\HOGEHAGE」の場合、区切り文字が2個なのでVM=3。</p> <h2 id="SQタグ"><a href="#SQ%E3%82%BF%E3%82%B0">SQタグ</a></h2> <p>ちょっと特殊なタグでこのタグ自体に値はないが子供を持つことができるタグ<br /> 例えばこんな風に</p> <pre><code>Referenced SOP Sequence(0008,1199)[SQ] >Referenced SOP Class UID(0008,1150)[UI] >Referemced SOP Instance UID(0008,1155)[UI] </code></pre> <p>※親子関係を表すのに">"を使う</p> <p>バイナリ的にはまた複雑でPS3.5の7.5.2を参照した方が早い。<br /> おそらくすごいこんがらがるから実際のデータをバイナリエディタで開きながら見たほうがいい。<br /> ポイントは<br /> * SQもVM複数のことがある<br /> * SQの場合、他のタグの値に当たる部分に、さらにItemがあり、他のタグと同様のセットが現れる<br /> * 長さが分からないときに区切りになるタグが存在する<br /> * (FFFE,E000)、(FFFE,E00D)、(FFFE,E0DD)に注意する</p> <p>このへんを頭に入れながら一つずつ読み解いていくとそのうち理解できるはず。</p> <h2 id="Type"><a href="#Type">Type</a></h2> <p>SOPごとに必要なタグ、あったらいいななタグなど違ってくるので、それぞれの場合の必要度を示すものがType、なぜかDICOM C/SではTypeで書かない(VNAPとかで書く)。<br /> * Type1:必ず必要、値も必要。=ALWAYS<br /> * Type2:タグは必ず必要、ただし値はなくてもいい。=VNAP(Value Not Always Present)<br /> * Type3:タグも値もなくてもいい。=ANAP(Attribute Not Always Present)<br /> * Type1C:Conditionを満たす場合Type1として振る舞う。</p> <hr /> <p>とりあえずここまで。</p> RedCol tag:crieit.net,2005:PublicArticle/15527 2019-11-04T05:43:52+09:00 2019-11-04T07:56:20+09:00 https://crieit.net/posts/Flutter Flutterに入門してつまったところ。電卓アプリを作りながら。その1 <p>最近、やっとFlutterに入門。。</p> <p>こんな電卓アプリを作りながら、Flutterのことを理解している最中。<br /> その際に、悩んだ点や調べた内容の備忘録。</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">とりあえず、ボタンを押すと、上の絵が変わるところまでできた(*´ω`*) <a target="_blank" rel="nofollow noopener" href="https://t.co/Ty8npyo3eO">pic.twitter.com/Ty8npyo3eO</a></p>— 積読ハウマッチ📚きらぷか (@kira_puka) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/kira_puka/status/1191079119695466497?ref_src=twsrc%5Etfw">November 3, 2019</a></blockquote> <p>以下の記事の続き的な内容。<br /> 1. <a target="_blank" rel="nofollow noopener" href="https://www.memory-lovers.blog/entry/2019/11/01/070000">Flutterに入門する前に集めたリンク集 - くらげになりたい。</a><br /> 2. <a target="_blank" rel="nofollow noopener" href="https://www.memory-lovers.blog/entry/2019/11/02/080000">Flutterに入門して疑問に思ったことと、そのとき調べたこと - くらげになりたい。</a></p> <h4 id="背景画像をつけたい"><a href="#%E8%83%8C%E6%99%AF%E7%94%BB%E5%83%8F%E3%82%92%E3%81%A4%E3%81%91%E3%81%9F%E3%81%84">背景画像をつけたい</a></h4> <p>Containerのdecorationを使うといける</p> <pre><code class="dart">class Background extends StatelessWidget { Background({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage("images/background.png"), fit: BoxFit.fill), ), ); } } </code></pre> <p>参考: <a target="_blank" rel="nofollow noopener" href="https://qiita.com/nemui-fujiu/items/8c381eca54b35f9350b1">Flutterで画像背景を設定して透過ヘッダーにする - Qiita</a></p> <h4 id="AppBarがないときに、ステータスバーにかぶらないようにしたい"><a href="#AppBar%E3%81%8C%E3%81%AA%E3%81%84%E3%81%A8%E3%81%8D%E3%81%AB%E3%80%81%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%83%90%E3%83%BC%E3%81%AB%E3%81%8B%E3%81%B6%E3%82%89%E3%81%AA%E3%81%84%E3%82%88%E3%81%86%E3%81%AB%E3%81%97%E3%81%9F%E3%81%84">AppBarがないときに、ステータスバーにかぶらないようにしたい</a></h4> <p>SafeAreaで囲むといけた</p> <pre><code class="dart"> @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: //..., ), ); } </code></pre> <p>参考: <a target="_blank" rel="nofollow noopener" href="https://qiita.com/coka__01/items/dedb569f6357f1b503fd#safearea">SafeArea | Flutter開発する前に知っておきたい35のWidget一覧 - Qiita</a></p> <h4 id="HexColorで色を指定したい"><a href="#HexColor%E3%81%A7%E8%89%B2%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E3%81%84">HexColorで色を指定したい</a></h4> <p>標準ライブラリにはないっぽい?<br /> 標準クラスをextendsして自作した。</p> <pre><code class="dart">import 'dart:ui'; class HexColor extends Color { static int _getColorFromHex(String hexColor) { hexColor = hexColor.toUpperCase().replaceAll("#", ""); if (hexColor.length == 6) { hexColor = "FF" + hexColor; } return int.parse(hexColor, radix: 16); } HexColor(final String hexColor) : super(_getColorFromHex(hexColor)); } </code></pre> <p>使い方はこんな感じ。</p> <pre><code class="dart">import './HexColor.dart'; class ColorText extends StatelessWidget { @override Widget build(BuildContext context) { return Text( "123456789", style: TextStyle( color: HexColor("#4D4DAC"), ), ); } } </code></pre> <p>参考: <a target="_blank" rel="nofollow noopener" href="https://www.it-swarm.net/ja/colors/flutter%E3%81%A716%E9%80%B2%E6%95%B0%E3%81%AE%E3%82%AB%E3%83%A9%E3%83%BC%E6%96%87%E5%AD%97%E5%88%97%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/838917297/">colors — Flutterで16進数のカラー文字列を使用する方法</a></p> <h4 id="ImageButtonみたいに、画像にクリックイベントをつける"><a href="#ImageButton%E3%81%BF%E3%81%9F%E3%81%84%E3%81%AB%E3%80%81%E7%94%BB%E5%83%8F%E3%81%AB%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E3%81%A4%E3%81%91%E3%82%8B">ImageButtonみたいに、画像にクリックイベントをつける</a></h4> <p>ImageをGestureDetectorで囲むと、イベントを取得できるっぽい。</p> <pre><code class="dart">return GestureDetector( onTap: () => debugPrint("onTap"), child: Image.asset("image/button.png"), ); </code></pre> <p>参考: <a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/53641053/create-a-button-with-an-image-in-flutter/53641444">Create a button with an image in Flutter? - Stack Overflow</a><br /> 参考: <a target="_blank" rel="nofollow noopener" href="https://inducesmile.com/google-flutter/how-to-add-on-click-event-to-image-in-flutter/">How to add on click event to Image in Flutter</a></p> <h4 id="コンソールログを表示する"><a href="#%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%83%AD%E3%82%B0%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B">コンソールログを表示する</a></h4> <p>いろいろ書き方があるっぽい。</p> <pre><code class="dart">// stderr.writeln stderr.writeln('print me'); // print, debugPrint print("print messaage"); debugPrint("debugPrint messaage"); // developer.log developer.log('log me', name: 'my.app.category'); developer.log('log me 1', name: 'my.other.category'); developer.log('log me 2', name: 'my.other.category'); // developer.log + error developer.log( 'log me', name: 'my.app.category', error: jsonEncode(myCustomObject), ); </code></pre> <p>参考: <a target="_blank" rel="nofollow noopener" href="https://flutter.dev/docs/testing/code-debugging#logging">Debugging Flutter apps programmatically - Flutter</a><br /> 参考: <a target="_blank" rel="nofollow noopener" href="https://qiita.com/kappaLab/items/602fcdaaa076efa59c3b">Flutter で print 出力を得たい - Qiita</a></p> <h4 id="Widgetのツリー構造を確認したい"><a href="#Widget%E3%81%AE%E3%83%84%E3%83%AA%E3%83%BC%E6%A7%8B%E9%80%A0%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%97%E3%81%9F%E3%81%84">Widgetのツリー構造を確認したい</a></h4> <p>Dev ToolのWidget Inspectionを使う。<br /> Androidの<a target="_blank" rel="nofollow noopener" href="https://developer.android.com/studio/debug/layout-inspector?hl=ja">Layout Inspector</a>みたいなやつ。</p> <p><img src="https://flutter.dev/assets/tools/devtools/inspector-3e6fa95156e6a794c715af44e0a85e45609c710f3fe20a24dfac5002fa8d58e0.gif" alt="Dev Tool" /></p> <p>参考: <a target="_blank" rel="nofollow noopener" href="https://flutter.dev/docs/testing/debugging#devtools">Debugging Flutter apps - Flutter</a></p> <h4 id="HotReloadが効かない(buildしても再生成されない書き方をしてた)"><a href="#HotReload%E3%81%8C%E5%8A%B9%E3%81%8B%E3%81%AA%E3%81%84%28build%E3%81%97%E3%81%A6%E3%82%82%E5%86%8D%E7%94%9F%E6%88%90%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84%E6%9B%B8%E3%81%8D%E6%96%B9%E3%82%92%E3%81%97%E3%81%A6%E3%81%9F%29">HotReloadが効かない(buildしても再生成されない書き方をしてた)</a></h4> <p>buildしても再生成されない書き方をしてた...</p> <p>だめな例。</p> <pre><code class="dart">class _PageState extends State<Page> { Widget _widget = Text("aaaa"); // ←だめなところ @override Widget build(BuildContext context) { return Scaffold( body: _widget, ); } } </code></pre> <p>良い例。</p> <pre><code class="dart">class _PageState extends State<Page> { @override Widget build(BuildContext context) { return Scaffold( body: Text("aaaa"), ); } } </code></pre> <h5 id="追記"><a href="#%E8%BF%BD%E8%A8%98">追記</a></h5> <p>つぶやいたら、monoさんから詳細を教えてもらえた(<em>´ω`</em>)<br /> 一連のリプの解説にもある通り、<code>const</code>をつけないと、キャッシュが使われるよう。</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">WidgetのキャッシュとHot Reloadが効くか否かの関係はこんな感じ( ´・‿・`)<a target="_blank" rel="nofollow noopener" href="https://t.co/fjG2ropgXs">https://t.co/fjG2ropgXs</a> <a target="_blank" rel="nofollow noopener" href="https://t.co/H4PUhW3v3u">https://t.co/H4PUhW3v3u</a> <a target="_blank" rel="nofollow noopener" href="https://t.co/kqqBFFvOt1">pic.twitter.com/kqqBFFvOt1</a></p>— mono 🎯 @自宅 (@_mono) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/_mono/status/1191115093964021760?ref_src=twsrc%5Etfw">November 3, 2019</a></blockquote> <p>公式ドキュメントではここ(<a target="_blank" rel="nofollow noopener" href="https://flutter.dev/docs/development/tools/hot-reload#recent-code-change-is-included-but-app-state-is-excluded">Hot reload - Flutter</a>)に、monoさんの<a target="_blank" rel="nofollow noopener" href="https://link.medium.com/yO7z0B7PL0">別の記事</a>でも解説されている。</p> <h4 id="フォーマッターでいい感じに整形されない"><a href="#%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%82%BF%E3%83%BC%E3%81%A7%E3%81%84%E3%81%84%E6%84%9F%E3%81%98%E3%81%AB%E6%95%B4%E5%BD%A2%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84">フォーマッターでいい感じに整形されない</a></h4> <p>末尾のコンマをつけていないので、いい感じにならないっぽい。<br /> 参考記事をみると「<strong>末尾コンマは大事</strong>」と書いてあった。</p> <blockquote> <p>Dartの末尾コンマは大事<br /> Dartの末尾コンマはその有無によってdartfmt結果が変わったりします。<br /> Using trailing commasに以下の図とともに説明されているように、<br /> 基本的には末尾に ”,” を入れた方がきれいかつ横幅もコンパクトに整形されます。</p> </blockquote> <p>参考: <a target="_blank" rel="nofollow noopener" href="https://medium.com/flutter-jp/tips-b2487a63a8">Flutterでの開発をスムーズに行うためのTips集 - Flutter 🇯🇵 - Medium</a></p> <h1 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h1> <p>以下の記事、IDEの機能の紹介やリファクタのTipsもたくさんあるので、<br /> 開発前に以下の記事に目を通すとだいぶ楽になる。。<br /> - <a target="_blank" rel="nofollow noopener" href="https://medium.com/flutter-jp/tips-b2487a63a8">Flutterでの開発をスムーズに行うためのTips集 - Flutter 🇯🇵 - Medium</a></p> <p>やっと、UIができた感じなので、すこしずつ作っていく。<br /> また進んだら、「その2」を調べたところをまとめていく予定〜</p> <h2 id="こんなのつくってます!!"><a href="#%E3%81%93%E3%82%93%E3%81%AA%E3%81%AE%E3%81%A4%E3%81%8F%E3%81%A3%E3%81%A6%E3%81%BE%E3%81%99%21%21">こんなのつくってます!!</a></h2> <p>積読用の読書管理アプリ 『積読ハウマッチ』をリリースしました!<br /> <a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>は、Nuxt.js+Firebaseで開発してます!</p> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="200"/></p> <p>もしよかったら、遊んでみてくださいヽ(=´▽`=)ノ</p> <p>要望・感想・アドバイスなどあれば、<br /> 公式アカウント(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/MemoryLoverz">@MemoryLoverz</a>)や開発者(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/kira_puka">@kira_puka</a>)まで♪</p> きらぷか@積読ハウマッチ/SSSAPIなど