title: Python: How to control Lineedit input and output in PyQt
body: <p>The code posted below creates a simple dialog window with only widget: <strong>QLineEdit</strong>.
  Typing anything into this field triggers fixText() method (on textChanged) which cleans an incoming string argument. After a string was 'cleaned' the method updates the QLineEdit with the result.</p>
  
  <p><strong>The goal:</strong> regardless of what user types in to the lineedit field:</p>
  
  <p>The first four letters are always uppercase. 
  The fifth character is always underscore. </p>
  
  <p>Remaining characters in a string don't have to be cleaned beyond of what cleanupString() does.</p>
  
  <p>Example of what needs to be achieved: <strong>ABCD_helloWorld</strong></p>
  
  <p><strong>A problem encountered:</strong> Unable to insert an underscore character without messing things up.
  The lines of the code responsible for insertion of underscore are currently commented...</p>
  
  <pre><code>import sys, os
  from PyQt4 import QtCore, QtGui  
  class Dialog_01(QtGui.QMainWindow):
      def __init__(self):
          super(QtGui.QMainWindow,self).__init__()
  
          myQWidget = QtGui.QWidget()
          myBoxLayout = QtGui.QVBoxLayout()       
  
  
          self.myQLineEdit = QtGui.QLineEdit("Type text here")
          self.myQLineEdit.textChanged.connect(self.fixText)
  
          myBoxLayout.addWidget(self.myQLineEdit)        
  
          myQWidget.setLayout(myBoxLayout)
          self.setCentralWidget(myQWidget)
          self.setWindowTitle('Dialog 01')
  
      def fixText(self, arg):
          arg=str(arg)
          if not arg: return
  
          arg=self.cleanupString(arg)
  
          if len(arg)&lt;3: result=arg.upper()
          else:     result = arg[0:4].upper()+arg[4:]
          # resultList=list(result)
          # resultList.insert(4, '_')
          # result=''.join(resultList)
          self.myQLineEdit.blockSignals(True)
          self.myQLineEdit.setText(result)
          self.myQLineEdit.blockSignals(False)
  
      def cleanupString(self, line=None):
          if line==None: return
          invalid = invalid = ['!','"','#','$','%','&amp;','\\','(',')','*','+',',','-','.','/'
                      ,':',';','&lt;','=','&gt;','?','@','[',"'",']','^','`','{','|','}','~', ' ']
          for c in invalid: 
              if len(line)&gt;0: line=line.replace(c,'_')
          return line
  
  
  if __name__ == '__main__':
      app = QtGui.QApplication(sys.argv)
      dialog_1 = Dialog_01()
      dialog_1.show()
      dialog_1.resize(480,320)
      sys.exit(app.exec_())
  </code></pre>
  
  <h1>FIXED CODE:</h1>
  
  <pre><code>import sys, os
  from PyQt4 import QtCore, QtGui    
  
  class Dialog_01(QtGui.QMainWindow):
      def __init__(self):
          super(QtGui.QMainWindow,self).__init__()
  
          myQWidget = QtGui.QWidget()
          myBoxLayout = QtGui.QVBoxLayout()       
  
  
          self.myQLineEdit = QtGui.QLineEdit("Type text here")
          self.myQLineEdit.textChanged.connect(self.fixText)
  
          myBoxLayout.addWidget(self.myQLineEdit)        
  
          myQWidget.setLayout(myBoxLayout)
          self.setCentralWidget(myQWidget)
          self.setWindowTitle('Dialog 01')
  
      def fixText(self, arg):
          arg=str(arg)
          if not arg: return
  
          arg=self.cleanupString(arg)
  
          if len(arg)&lt;=3: result=arg.upper()
          else:     result = arg[0:4].upper()+"_"+arg[5:]
  
          self.myQLineEdit.blockSignals(True)
          self.myQLineEdit.setText(result)
          self.myQLineEdit.blockSignals(False)
  
      def cleanupString(self, line=None):
          if line==None: return
          invalid = invalid = ['!','"','#','$','%','&amp;','\\','(',')','*','+',',','-','.','/'
                      ,':',';','&lt;','=','&gt;','?','@','[',"'",']','^','`','{','|','}','~', ' ']
          for c in invalid: 
              if len(line)&gt;0: line=line.replace(c,'_')
          return line
  
  if __name__ == '__main__':
      app = QtGui.QApplication(sys.argv)
      dialog_1 = Dialog_01()
      dialog_1.show()
      dialog_1.resize(480,320)
      sys.exit(app.exec_())
  </code></pre>