[python]構音障害かつ小脳失調を持つ人のための文字入力ソフト

PyQtを用いて,構音障害かつ小脳失調を呈している人向けの文字入力ソフトを作成してみた.一種類のクリックだけで50音の文字入力と文字の削除が可能です.小文字の入力が出来ないのはご愛嬌です.

windowのサイズの調整,枠の大きさの調整は環境によって必要になってくるかと思います.

実際に試してみた患者さんは,多系統萎縮症の患者さんに対してでした. 

# usr/bin/python3
# coding:utf-8


import sys
import os
import time 
import numpy as np
import itertools

from PyQt5 import QtWidgets 
from PyQt5.QtCore import Qt, QTimer

import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas 
from matplotlib import animation
plt.rcParams['font.family'] = 'IPAPGothic' 


class Application(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()

        # set parameters 
        self.interval = 1000
        self.fontSize = 48
        self.path2Save = "text.txt"
        self.maxNumText = 17
    
        # init objects
        self.resText = "ここにテキストが表示されます"

        self.initUI()
        self.initFigure()

        self.resText = ""

        # timer setting
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update)
        self.stopFlag = False
        self.waitFlag = False 
        self.waitOne = False

        # word setting 
        self.phase = 0
        self.dict1= ["あ","は","゛","゜","削除" ]
        self.words1 = itertools.cycle(self.dict1)
        self.dict2= { "あ" : "あかさたな", "は": "はまやらわ、"}
        self.dict3= { "あ" : "あいうえお", 
                    "か":"かきくけこ",
                    "さ":"さしすせそ",
                    "た":"たちつてと",
                    "な":"なにぬねの",
                    "は":"はひふへほ",
                    "ま":"まみむめも",
                    "や":"やゆよ",
                    "ら":"らりるれろ",
                    "わ":"わをんー",
                    "、":"、。?!「」"
                    }



    def initUI(self):
        # For FigureWidget
        self.FigureWidget = QtWidgets.QWidget(self)
        # make FigureLayout. This FigureLayout will be added by vbox.
        self.FigureLayout = QtWidgets.QVBoxLayout(self.FigureWidget)
        # delete margin 
        self.FigureLayout.setContentsMargins(0,0,0,0)

        btn1 = QtWidgets.QPushButton("Click")
        btn1.clicked.connect(self.buttonClicked)
        btn2 = QtWidgets.QPushButton("Stop")
        btn2.clicked.connect(self.buttonClicked2)
        btn3 = QtWidgets.QPushButton("Reset")
        btn3.clicked.connect(self.buttonClicked3)

        def setSpinValue(value):
            self.interval = value

            if not self.stopFlag :
                self.timer.stop() 
                self.stopFlag = True
        spin1 = QtWidgets.QSpinBox()
        spin1.setRange(1,10000)
        spin1.setSingleStep(1)
        spin1.setValue(2000)
        spin1.valueChanged.connect(setSpinValue)
        spinLabel = QtWidgets.QLabel("")#"間隔(ms)")

        self.hbox = QtWidgets.QHBoxLayout()
        self.hbox.addWidget(spinLabel)
        self.hbox.addWidget(spin1)
        self.hbox.addWidget(btn3)
        self.hbox.addWidget(btn2)
        self.hbox.addWidget(btn1)


        ##### alinment  #####
        nx = 1400
        ny = 700

        #self.hbox(nx*0.5,ny*0.9)
        #btn1.move(nx*0.8,ny*0.9)
        #btn2.move(nx*0.7,ny*0.9)
        #btn3.move(nx*0.6,ny*0.9)
        #spin1.move(nx*0.5,ny*0.92)
        self.setGeometry(0,0,nx*0.9,ny)
        self.FigureWidget.setGeometry(0,0,nx*0.9,ny*0.97)

    def initFigure(self):
        # make Figure
        self.Figure = plt.figure()
        # add Figure to FigureCanvas
        self.FigureCanvas = FigureCanvas(self.Figure)

        # add FigureCanvas to Layout
        self.FigureLayout.addWidget(self.FigureCanvas)

        # for control panel 
        self.FigureLayout.addLayout(self.hbox)

        self.axis = self.Figure.add_subplot(1,1,1)
        self.setPositionHiragana()
        self.hiraganaTable()

    def buttonClicked(self):
        sender = self.sender()

        if self.stopFlag==True:
            self.timer.start(self.interval)
            self.stopFlag = False
            return(0)
            
        if self.waitOne:
            return(0)
        self.waitFlag = True

        # phase actions
        if self.phase == 0:
            self.timer.start(self.interval) # ms
            self.phase = 1 
            self.word = "あ"
            self.statusBar().showMessage("Phase 1")

        elif self.phase == 1 : 
            if self.word == "あ" or self.word == "は": 
                self.phase = 2 
                self.statusBar().showMessage("Phase 2")
                self.words2 = itertools.cycle(self.dict2[self.word])
                self.plotWord = self.word
            else:
                self.phase = 1 
                self.statusBar().showMessage("Phase 1")
                self.words1 = itertools.cycle(self.dict1)

                if self.word == "削除":
                    self.resText = self.resText[:-1]
                #elif self.word == "空白":
                #    self.resText += " "
                else:
                    self.resText += self.word

        elif self.phase == 2: 
            self.phase = 3 
            self.statusBar().showMessage("Phase 3")
            self.words3 = itertools.cycle(self.dict3[self.word])
            self.plotWord = self.word

        elif self.phase == 3:
            self.phase = 1 
            self.statusBar().showMessage("Phase 1")
            self.resText += self.word
            self.words1 = itertools.cycle(self.dict1)

        # text display options
        if len(self.resText) > self.maxNumText:
            while len(self.resText) > self.maxNumText:

                with open(self.path2Save, "a") as f: 
                    f.write(self.resText[0]) 
                self.resText = self.resText[1:]

    def buttonClicked2(self):
        sender = self.sender()
        self.statusBar().showMessage("button was clicked")

        self.timer.stop() 
        self.stopFlag = True

    def buttonClicked3(self):
        sender = self.sender()
        self.statusBar().showMessage("button was clicked")

        self.resText = ""

    def update(self):
        self.axis.clear()
        if self.waitFlag:
            self.waitFlag = False
            self.waitOne = True

            self.hiraganaTable()
            self.writeRed("待機")

            if self.phase == 1:
                self.region1()
            elif self.phase == 2:
                self.region2(self.plotWord)
            elif self.phase == 3:
                self.region3(self.plotWord)
            self.FigureCanvas.draw()
            return(0)
        else:
            self.waitOne = False

        if self.phase == 1:
            self.word = self.words1.__next__()
            self.hiraganaTable()
            self.writeRed(self.word)
            self.region1()

        elif self.phase == 2:
            self.word = self.words2.__next__()
            self.hiraganaTable()
            self.writeRed(self.word)
            self.region2(self.plotWord)

        elif self.phase == 3:
            self.word = self.words3.__next__()
            self.hiraganaTable()
            self.writeRed(self.word)
            self.region3(self.plotWord)

        self.FigureCanvas.draw()

    def setPositionHiragana(self):
        base1 = "あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめも"
        base2 = "やゆよ"
        base3 = "らりるれろ"
        base4 = "わをんー"
        base5 = "、。?!「」"
        base6 = ["゛","゜","削除"] 

        self.x = 0
        self.y = 1.5
        x = self.x
        y = self.y

        self.pos= {}
        for i in range(7):
            for j in range(5):
                self.pos[base1[j + i*5] ] = [x+ i, y+5-j]

        for i ,j in enumerate([0,2,4]):
            self.pos[base2[i]] = [x+7, y+5-j]

        for i in range(5):
            self.pos[ base3[i]] = [x +8 , y+5-i]

        for i, j in enumerate([0,1,2,3]):
            self.pos[ base4[i] ] = [x+9, y + 5- j]

        for i in range(6):
            self.pos[ base5[i] ] = [x+ 10, y + 5-i]

        for i,t in enumerate(base6):    
            self.pos[ t ] = [x+ 5 + i , y+ -0.5]

        self.pos["待機"] = [ x , y + 6.5]

    def hiraganaTable(self):
        self.axis.set_xlim([-1,11])
        self.axis.set_ylim([0,8])
        for k,v in self.pos.items():
            if k == "待機" :
                size = self.fontSize - 5
            else: 
                size = self.fontSize
            self.axis.text(v[0],v[1],k, fontsize = size)

        self.axis.text(self.x, self.y - 2, self.resText,fontsize=self.fontSize - 5)


        self.axis.get_xaxis().set_visible(False)
        self.axis.get_yaxis().set_visible(False)
        self.axis.spines["right"].set_visible(False)
        self.axis.spines["left"].set_visible(False)
        self.axis.spines["top"].set_visible(False)
        self.axis.spines["bottom"].set_visible(False)
        
    def writeRed(self,str_):
        v = self.pos[str_]
        if str_ == "待機" :
            size = self.fontSize - 5
        else: 
            size = self.fontSize
        self.axis.text(v[0],v[1],str_,color="red", fontsize = size)

    def region1(self):
        for w in ["あ","は","゛","゜"]:
            v = self.pos[w]
            dif = 0.05
            difP = 0.95
            x0 = v[0] - dif  
            y0 = v[1] - dif 
            xx = [ x0 , x0 , x0 + difP , x0 + difP, x0 ]
            yy = [ y0 , y0 + difP + 0.05 , y0 + difP + 0.05 , y0 , y0 ]
            self.axis.plot(xx,yy,color = "green")

        v = self.pos["削除"]
        x0 = v[0] - dif  
        y0 = v[1] - dif 
        addDif = 1.65 
        xx = [ x0 , x0 , x0 + dif + addDif , x0 + dif + addDif, x0 ]
        yy = [ y0 , y0 + difP , y0 + difP , y0 , y0 ]
        self.axis.plot(xx,yy,color = "green")

    def region2(self,str_):
        v = self.pos[str_]
        dif = 0.05
        difP = 0.95
        x0 = v[0] - dif
        y0 = v[1] - dif
        if str_ == "あ":
            addDif = 4.8
        else:
            addDif = 5.8
        xx = [ x0 , x0 , x0 + dif + addDif , x0 + dif + addDif, x0 ]
        yy = [ y0 , y0 + difP , y0 + difP , y0 , y0 ]
        self.axis.plot(xx,yy,color = "green")

    def region3(self,str_):
        v = self.pos[str_]
        dif = 0.05
        difP = 0.95
        x0 = v[0] - dif
        y0 = v[1] - dif + difP 
        if str_ == "、":
            addDif = 6
        else:
            addDif = 5

        xx = [ x0 , x0, x0 + difP, x0 + difP, x0 ]
        yy = [ y0, y0 -addDif, y0 - addDif , y0 , y0]
        self.axis.plot(xx,yy,color = "green")

if __name__=="__main__":
    app = QtWidgets.QApplication(sys.argv)
    qapp = Application()
    qapp.show()
    sys.exit(app.exec_())


コメント

タイトルとURLをコピーしました