5

I had drawn up an UI using the QT Designer but found out that there are no parameters for me to set QLineEdit inputs to be uppercase.

After doing some online searching, I have only seen a very few handful of results that cater to my needs, however all are coded in Qt. Example, this link

And so, are there ways for me to do this in the pythonic way?

dissidia
  • 1,531
  • 3
  • 23
  • 53
  • First of all, your link is about C++, not Python. Then, why not use just `string_got_from_lineEdit.upper()`? – ForceBru Mar 10 '15 at 11:17
  • @ForceBru `upper()` is used after the user has inputted in, then it was converted to upper case, no? What I wanted was uppercase the moment user was going to input something. – dissidia Mar 10 '15 at 11:26

4 Answers4

10

The simplest way would be to use a validator.

This will immediately uppercase anything the user types, or pastes, into the line-edit:

from PyQt4 import QtCore, QtGui

class Validator(QtGui.QValidator):
    def validate(self, string, pos):
        return QtGui.QValidator.Acceptable, string.upper(), pos
        # for old code still using QString, use this instead
        # string.replace(0, string.count(), string.toUpper())
        # return QtGui.QValidator.Acceptable, pos

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.edit = QtGui.QLineEdit(self)
        self.validator = Validator(self)
        self.edit.setValidator(self.validator)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.edit)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 300, 100)
    window.show()
    sys.exit(app.exec_())
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • While trying out, I am getting the following error - `# AttributeError: 'QString' object has no attribute 'upper'` and it comes from the `return` statement in the `class Validator`. – dissidia Mar 11 '15 at 02:37
  • 1
    @dissidia. If you're still using the obsolete `QString` APIs, a slightly different method is required. See my updated answer. – ekhumoro Mar 11 '15 at 18:29
  • Your answer works! Thank you so much. Question though - how do I know if I am using the obsolete `QString` APIs or not? – dissidia Mar 12 '15 at 03:10
  • 1
    @dissidia. For PyQt4 with Python2, you get `QString` by default; but with Python3, you get normal python strings by default. However, it's possible to change these defaults using [sip.setapi](http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html). For PyQt5, there is no `QString` support at all, which is why I said those APIs are obsolete. As you can see from my answer above, PyQt code is generally a lot simpler when you don't have to deal with `QString` (and the same goes for `QVariant`). – ekhumoro Mar 12 '15 at 17:59
3

Try this, I believe this serves your purpose. I won't call it much pythonic. More like PyQt override.

#minor code edit

from PyQt4 import QtGui
import sys
#===============================================================================
# MyEditableTextBox-  
#===============================================================================
class MyEditableTextBox(QtGui.QLineEdit):
#|-----------------------------------------------------------------------------|
# Constructor  
#|-----------------------------------------------------------------------------|

    def __init__(self,*args):
        #*args to set parent
        QtGui.QLineEdit.__init__(self,*args)

#|-----------------------------------------------------------------------------|
# focusOutEvent :- 
#|-----------------------------------------------------------------------------|
    def focusOutEvent(self, *args, **kwargs):
        text = self.text()
        self.setText(text.__str__().upper())
        return QtGui.QLineEdit.focusOutEvent(self, *args, **kwargs)


#|--------------------------End of focusOutEvent--------------------------------|
#|-----------------------------------------------------------------------------| 
# keyPressEvent
#|-----------------------------------------------------------------------------|
    def keyPressEvent(self, event):
        if not self.hasSelectedText():
            pretext = self.text()
            self.setText(pretext.__str__().upper())
        return QtGui.QLineEdit.keyPressEvent(self, event)

#|--------------------End of keyPressEvent-------------------------------------|

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    w = QtGui.QWidget()
    lay = QtGui.QHBoxLayout()
    w.setLayout(lay)
    le1 = MyEditableTextBox()
    lay.addWidget(le1)
    le2 = MyEditableTextBox()
    lay.addWidget(le2)
    w.show()
    sys.exit(app.exec_())
smitkpatel
  • 722
  • 6
  • 21
  • I am getting the error - `# AttributeError: 'QString' object has no attribute 'upper'`, it comes from the `focusOutEvent` function - `self.setText(text.upper())` Also, the QLineEdit is not registering in the characters I have typed in, probably due to the error – dissidia Mar 11 '15 at 02:42
  • What qt/pyqt and python versions are you using? it is working fine in my case. you might want to replace the calls to upper in focusOutEvent and keyPressEvent with the following: text.__str__().upper() and pretext.__str__().upper() ... just edited the code for that... – smitkpatel Mar 11 '15 at 05:09
  • These are my versions - ('Qt version:', '4.8.2') and ('PyQt version:', '4.9.6') – dissidia Mar 11 '15 at 07:08
  • yea, it works but I realized that the last character that I am typing is in lowercase, eg. "FIVe", unless another character was typed or spacebar was pressed. Just wondering is it supposed to be like this? – dissidia Mar 11 '15 at 07:55
  • yes.. it is supposed to be like this. that is why the final character turns to uppercase only on focus out or if you press any other key that is not typed... otherwise.. if you do not need to necessarily stick to QLineEdit then @ekhumoro's answer works just fine... – smitkpatel Mar 11 '15 at 07:58
  • Thanks for letting me know. I will try playing around with your solution. Apparently as mentioned, I am getting the same initial error in @ekhumoro's answer too. Would like to get a second opinion on the current issue. But thanks again as this is totally what I am looking for :) – dissidia Mar 11 '15 at 08:06
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/72740/discussion-between-smitkpatel-and-dissidia). – smitkpatel Mar 11 '15 at 08:28
  • 2
    @smitkpatel. You can eliminate the problem with the last character typed by calling `QLineEdit.keyPressEvent` *before* re-setting the text (and note that you don't need the `return`). Also, a simpler way to reset the text is with `self.setText(self.text().toUpper())`. – ekhumoro Mar 11 '15 at 18:48
3

Hey I know I am kind of late, but I hope this might help some one else like me who spent some time searching for this

Mycase: I was trying to convert only the first letter to capital and this is what I ended up with and it worked (just a beginner in python so if you can make this more pythonic please let me know)

In the defining function: line_edit_object.textChanged.connect(lambda:auto_capital(line_edit_object))

the function auto_capital:

def auto_capital(line_edit_object):
    edit=line_edit_object
    text=edit.text()
    edit.setText(text.title())

this shall fix every issue. Feel free to make it more pythonic.

Ja8zyjits
  • 1,433
  • 16
  • 31
0

I am also late but after contemplating on this question I think this is some sort of pythonic way of accomplishing it in PyQt5:

class CustomInput(QLineEdit):
    def __init__(self):
        super().__init__()
        self.textChanged.connect(self.text_changed)
    
    def text_changed(self):
        if self.text().isupper():
            return
        self.setText(self.text().upper())
Atalay
  • 26
  • 2