Uppercase input in QLineEdit python way
Asked Answered
B

4

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?

Beachhead answered 10/3, 2015 at 11:15 Comment(2)
First of all, your link is about C++, not Python. Then, why not use just string_got_from_lineEdit.upper()?Bly
@Bly 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.Beachhead
M
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_())
Mange answered 10/3, 2015 at 11:58 Comment(8)
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 errorBeachhead
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...Mange
These are my versions - ('Qt version:', '4.8.2') and ('PyQt version:', '4.9.6')Beachhead
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?Beachhead
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...Mange
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 :)Beachhead
Let us continue this discussion in chat.Mange
@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()).Formation
F
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_())
Formation answered 10/3, 2015 at 20:50 Comment(4)
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.Beachhead
@dissidia. If you're still using the obsolete QString APIs, a slightly different method is required. See my updated answer.Formation
Your answer works! Thank you so much. Question though - how do I know if I am using the obsolete QString APIs or not?Beachhead
@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. 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).Formation
M
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_())
Mange answered 10/3, 2015 at 11:58 Comment(8)
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 errorBeachhead
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...Mange
These are my versions - ('Qt version:', '4.8.2') and ('PyQt version:', '4.9.6')Beachhead
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?Beachhead
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...Mange
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 :)Beachhead
Let us continue this discussion in chat.Mange
@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()).Formation
E
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.

Eakins answered 15/5, 2015 at 8:7 Comment(0)
D
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())
Duodecimo answered 30/7, 2022 at 18:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.