0

I would like to format nicely some text lines in a textbox. Of course I wanted to use string formatting but unfortunately something went wrong and I really don't know where.

That's my code which creates a window with a textbox and some "formatted" lines in it.

import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import * 
from PyQt5.QtCore import pyqtSlot, QSize, QRect

class PrintWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.title='Print something'
        self.left=10
        self.top=10
        self.width=640
        self.height=480
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left,self.top,self.width,self.height)

        self.statusBar().showMessage('In progress')

        # create textbox
        self.textbox = QTextEdit(self)
        self.textbox.move(50, 210)
        self.textbox.resize(540, 200)
        self.textbox.setReadOnly(True)
        # create textbox done

        self.show()

        data = []
        line1 = 'Some text'
        line2 = 50 * '-'
        line3 = "{:<10} {:<15} {:<25} {:<25} {:<25}".format('Number:', 'City:', 'Some info:', 'Person:', 'Date:')
        line4 = "{:<10} {:<15} {:<25} {:<25} {:<25}".format('1', 'Dublin', 'Yes', 'Gabriella Anderson', 'No date')
        line5 = "{:<10} {:<15} {:<25} {:<25} {:<25}".format('2', 'London', 'No', 'Daniel Wozniak', '2019-08-08')
        data.append(line1)
        data.append(line2)
        data.append(line3)
        data.append(line4)
        data.append(line5)
        self.textbox.setText("\n".join(data))

if __name__ == '__main__':

    app = QApplication(sys.argv)
    window = PrintWindow()
    sys.exit(app.exec_())

As I wrote above unfortunately it doesn't work and the window doesn't look nice. Window with a textbox

What is even more interesting I tried with a similar code in normal Python terminal. There it is

data = []
line1 = 'Some text'
line2 = 50 * '-'
line3 = "{:<10} {:<15} {:<25} {:<25} {:<25}".format('Number:', 'City:', 'Some info:', 'Person:', 'Date:')
line4 = "{:<10} {:<15} {:<25} {:<25} {:<25}".format('1', 'Dublin', 'Yes', 'Gabriella Anderson', 'No date')
line5 = "{:<10} {:<15} {:<25} {:<25} {:<25}".format('2', 'London', 'No', 'Daniel Wozniak', '2019-08-08')
data.append(line1)
data.append(line2)
data.append(line3)
data.append(line4)
data.append(line5)

for element in data:
    print(element)

Now the printed lines are perfect and they look as I expected. Lines in Python terminal

Where is the problem? What am I doing wrong?

Hendrra
  • 682
  • 1
  • 8
  • 19

2 Answers2

1

The font/typeface you are using in your QTextEdit widget is not monospaced. The characters will only line up nicely if every character has the same width (which they only do if the font/typeface is monospace). The characters line up in the terminal because the terminal uses a monospaced font/typeface by default.

https://upload.wikimedia.org/wikipedia/commons/f/f0/Proportional-vs-monospace-v4.jpg

Paul M.
  • 10,481
  • 2
  • 9
  • 15
  • Thanks. Can I ask for a tip how can I change the font type? – Hendrra Aug 08 '19 at 17:16
  • I've played around with this in the past. Just google something like "QTextEdit monospace font" and you'll find tons of threads. There seem to be a handful of different solutions (and I seem to recall that not all of them worked for me). I believe it's because there isn't one single cross-platform way of doing this. At a minimum, you'll probably have to create a QFont object, force it to be monospace (or apply a monospace font to the QFont object), and then apply the font object to your QTextEdit widget by doing something like self.textbox.setFont(font_object). – Paul M. Aug 08 '19 at 17:22
1

As others have suggested, you need a monospaced font where every character is the same width. Most fonts you come into contact with are proportional fonts (e.g. Arial, Times, Calibri, Helvetica) where character widths vary.

By default, Qt will use a proportional font for the GUI.

To change the font, you can use the setFont() method for most widgets. Here, I'm using Consolas, which is a Microsoft font, but Courier, Deja Vu Sans Mono, Liberation Mono, Lucida Console, etc. are OK, too.

import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import * 
from PyQt5.QtCore import pyqtSlot, QSize, QRect
from PyQt5.QtGui  import QFont

class PrintWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.title='Print something'
        self.left=10
        self.top=10
        self.width=640
        self.height=480
        self.initUI()


    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left,self.top,self.width,self.height)

        self.statusBar().showMessage('In progress')

        # create textbox
        self.textbox = QTextEdit(self)
        self.textbox.move(50, 210)
        self.textbox.resize(540, 200)
        self.textbox.setReadOnly(True)
        # create textbox done

        font = QFont("Consolas", 6)
        # either of the following lines will set the font comment/uncomment
        self.textbox.setFont(font)  # set font ONLY for textbox
        #self.setFont(font)         # set font for entire QMainWindow which
                                    # will propagate to all widgets

        self.show()

        data = []
        line1 = 'Some text'
        line2 = 50 * '-'
        line3 = "{:<10} {:<15} {:<25} {:<25} {:<25}".format('Number:', 'City:', 'Some info:', 'Person:', 'Date:')
        line4 = "{:<10} {:<15} {:<25} {:<25} {:<25}".format('1', 'Dublin', 'Yes', 'Gabriella Anderson', 'No date')
        line5 = "{:<10} {:<15} {:<25} {:<25} {:<25}".format('2', 'London', 'No', 'Daniel Wozniak', '2019-08-08')
        data.append(line1)
        data.append(line2)
        data.append(line3)
        data.append(line4)
        data.append(line5)
        self.textbox.setText("\n".join(data))

if __name__ == '__main__':

    app = QApplication(sys.argv)
    window = PrintWindow()
    sys.exit(app.exec_())

enter image description here

You can also use Qt Style Sheets to set the font. I couldn't get Style Sheets to work nicely in this example. But if you are using Qt Designer or Qt Creator to create your forms with nice layouts, Style Sheets can be really handy.

bfris
  • 5,272
  • 1
  • 20
  • 37