Ricky
Ricky

Reputation: 79

How can I insert an image in a QTextEdit?

So I'm trying to insert an image on a Qtexteditor, so far I only managed to turn the Qtexteditor all white, i tried this:

ACTIVATED_CSS = 'QTextEdit {image: url(einstein.jpg);}'

So I'm receiving some numbers from 1 to 7 (via TCP) in random order, and when the code receives them a corresponding Qtexteditor 'lights' up with a green bakground, but now I want to change to an image when lights up.

Here is my code:

import sys
import threading
import asyncio
import time
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from TcpClient import TcpClient
from play_wav_files import PlaySoundThread


NORMAL_HIDDEN_CSS = 'QTextEdit {background-color: black; font: 30px; color: white;}'
ACTIVATED_CSS = 'QTextEdit {color: red; font: 25px; background-color: green;  font-weight: bold; margin-top: 10px; margin-bottom: 20px; margin-left: 30px; margin-right: 30px;}'
NORMAL_CSS = 'QTextEdit {color: white; font: 25px; background-color: grey;  font-weight: bold; margin-top: 10px; margin-bottom: 20px; margin-left: 30px; margin-right: 30px;}'
ACTIVATED_CSS_AR = 'QTextEdit {color: red; font: 25px; background-color: green;  font-weight: bold; margin-top: 20px; margin-bottom: 40px; margin-left: 50px; margin-right: 50px;}'
NORMAL_CSS_AR = 'QTextEdit {color: white; font: 25px; background-color: grey;  font-weight: bold; margin-top: 20px; margin-bottom: 40px; margin-left: 50px; margin-right: 50px;}'
TCP_CLIENT = TcpClient()
EW_CONSTANT = TCP_CLIENT.nepoch * TCP_CLIENT.nwords
ASYNC_LOOP = asyncio.get_event_loop()

#TENTAR COM IMAGENS CARAS ------------------

#ACTIVATED_CSS = 'QTextEdit {image: url(einstein.jpg);}'
#ACTIVATED_CSS_AR = 'QTextEdit {image: url(einstein.jpg);}'

class QtSideGui(QDialog):

    def __init__(self):
        QDialog.__init__(self)

        # buttons:
        self.conn_button = QPushButton('Recieve server instructions')
        self.clear_button = QPushButton('Clear status')
        self.insert_code_1 = QPushButton('Insert Code 1')
        self.insert_code_update_1 = QPushButton('insert update code 1')
        self.insert_code_2 = QPushButton('Insert Code 2')
        self.insert_code_update_2 = QPushButton('insert update code 2')
        self.insert_code_3 = QPushButton('Insert Code 3')
        self.insert_code_update_3 = QPushButton('insert update code 3')
        self.insert_code_4 = QPushButton('Insert Code 4')
        self.insert_code_update_4 = QPushButton('insert update code 4')
        self.insert_code_5 = QPushButton('Insert Code 5')
        self.insert_code_update_5 = QPushButton('insert update code 5')
        self.insert_code_6 = QPushButton('Insert Code 6')
        self.insert_code_update_6 = QPushButton('insert update code 6')
        self.insert_code_7 = QPushButton('Insert Code 7')
        self.insert_code_update_7 = QPushButton('insert update code 7')
        self.insert_code_1.setHidden(True)
        self.insert_code_update_1.setHidden(True)
        self.insert_code_2.setHidden(True)
        self.insert_code_update_2.setHidden(True)
        self.insert_code_3.setHidden(True)
        self.insert_code_update_3.setHidden(True)
        self.insert_code_4.setHidden(True)
        self.insert_code_update_4.setHidden(True)
        self.insert_code_5.setHidden(True)
        self.insert_code_update_5.setHidden(True)
        self.insert_code_6.setHidden(True)
        self.insert_code_update_6.setHidden(True)
        self.insert_code_7.setHidden(True)
        self.insert_code_update_7.setHidden(True)
        self.clear_button.setHidden(True)

        # Text Boxes:
        self._l_blank1 = QTextEdit('')
        self._l_blank1.setStyleSheet(NORMAL_HIDDEN_CSS)
        self._l_blank2 = QTextEdit('')
        self._l_blank2.setStyleSheet(NORMAL_HIDDEN_CSS)
        self._l_blank3 = QTextEdit('')
        self._l_blank3.setStyleSheet(NORMAL_HIDDEN_CSS)
        self._l_blank4 = QTextEdit('')
        self._l_blank4.setStyleSheet(NORMAL_HIDDEN_CSS)
        self._l_blank5 = QTextEdit('')
        self._l_blank5.setStyleSheet(NORMAL_HIDDEN_CSS)
        self._l_blank6 = QTextEdit('')
        self._l_blank6.setStyleSheet(NORMAL_HIDDEN_CSS)
        self._updadeQText = QTextEdit('-')
        self._updadeQText.setStyleSheet(NORMAL_HIDDEN_CSS)

        self._l_sim = QTextEdit()
        self._l_sim.setText('                             SIM')
        self._l_sim.setAlignment(Qt.AlignCenter)
        self._l_sim.setStyleSheet(NORMAL_CSS)

        self._l_nao = QTextEdit()
        self._l_nao.setText('                             NÃO')
        self._l_nao.setAlignment(Qt.AlignCenter)
        self._l_nao.setStyleSheet(NORMAL_CSS)

        self._l_fome = QTextEdit()
        self._l_fome.setText('                             FOME')
        self._l_fome.setAlignment(Qt.AlignCenter)
        self._l_fome.setStyleSheet(NORMAL_CSS)

        self._l_sede = QTextEdit()  
        self._l_sede.setText('                             SEDE')
        self._l_sede.setAlignment(Qt.AlignCenter)
        self._l_sede.setStyleSheet(NORMAL_CSS)

        self._l_urinar = QTextEdit() 
        self._l_urinar.setText('                             URINAR')
        self._l_urinar.setAlignment(Qt.AlignCenter)
        self._l_urinar.setStyleSheet(NORMAL_CSS)

        self._l_ar = QTextEdit()
        self._l_ar.setText('                            AR')
        self._l_ar.setAlignment(Qt.AlignCenter)
        self._l_ar.setStyleSheet(NORMAL_CSS_AR)

        self._l_posicao = QTextEdit()
        self._l_posicao.setText('                             POSIÇÃO')
        self._l_posicao.setAlignment(Qt.AlignCenter)
        self._l_posicao.setStyleSheet(NORMAL_CSS)


        # Layout:
        self._layoutGL = QGridLayout()
        self._layoutGL.addWidget(self._l_sim, 3, 1)
        self._layoutGL.addWidget(self._l_nao, 3, 4)
        self._layoutGL.addWidget(self._l_fome, 4, 2)
        self._layoutGL.addWidget(self._l_sede, 4, 3)
        self._layoutGL.addWidget(self._l_urinar, 2, 1)
        self._layoutGL.addWidget(self._l_posicao, 2, 4)
        self._layoutGL.addWidget(self._l_blank1, 2, 2)
        self._layoutGL.addWidget(self._l_blank2, 2, 3)
        self._layoutGL.addWidget(self._l_blank3, 3, 3)
        self._layoutGL.addWidget(self._l_blank4, 3, 2)
        self._layoutGL.addWidget(self._l_blank5, 4, 1)
        self._layoutGL.addWidget(self._l_blank6, 4, 4)

        self._layoutH = QHBoxLayout()
        self._layoutH.addWidget(self._l_blank2,35.5)
        self._layoutH.addWidget(self._l_ar,29)
        self._layoutH.addWidget(self._l_blank3,35.5)
        self._layoutV = QVBoxLayout()
        self._layoutV.addWidget(self._updadeQText)
        self._layoutV.addLayout(self._layoutH)
        self._layoutV.addLayout(self._layoutGL)
        self._layoutV.addWidget(self.conn_button)
        self._layoutV.addWidget(self.clear_button)

        # instruct QDialog to display:
        self.setWindowTitle("Code receiver")
        self.setLayout(self._layoutV)
        self.setFocus()

        # QT signal and slots connections
        self.conn_button.clicked.connect(self.open_tcp_connection)
        self.clear_button.clicked.connect(self.set_all_down)
        self.insert_code_1.clicked.connect(self.set_sim_highlight)
        self.insert_code_update_1.clicked.connect(self.set_update_text_sim)
        self.insert_code_2.clicked.connect(self.set_nao_highlight)
        self.insert_code_update_2.clicked.connect(self.set_update_text_nao)
        self.insert_code_3.clicked.connect(self.set_fome_highlight)
        self.insert_code_update_3.clicked.connect(self.set_update_text_fome)
        self.insert_code_4.clicked.connect(self.set_sede_highlight)
        self.insert_code_update_4.clicked.connect(self.set_update_text_sede)
        self.insert_code_5.clicked.connect(self.set_urinar_highlight)
        self.insert_code_update_5.clicked.connect(self.set_update_text_urinar)
        self.insert_code_6.clicked.connect(self.set_ar_highlight)
        self.insert_code_update_6.clicked.connect(self.set_update_text_ar)
        self.insert_code_7.clicked.connect(self.set_posicao_highlight)
        self.insert_code_update_7.clicked.connect(self.set_update_text_posicao)

    # Useful methods:
    @staticmethod
    def pick_up_text_and_update(text, text_code):
        return text + '  ' + text_code

    def open_tcp_connection(self):
        threading.Thread(target=self._asyncio_thread, args=(ASYNC_LOOP,)).start()

    def set_update_text_sim(self):
        self._updadeQText.setText(self.pick_up_text_and_update(self._updadeQText.toPlainText(), 'SIM'))

    def set_sim_highlight(self):
        self._l_sim.setStyleSheet(ACTIVATED_CSS)

    def set_update_text_nao(self):
        self._updadeQText.setText(self.pick_up_text_and_update(self._updadeQText.toPlainText(), 'NÃO'))

    def set_nao_highlight(self):
        self._l_nao.setStyleSheet(ACTIVATED_CSS)

    def set_update_text_fome(self):
        self._updadeQText.setText(self.pick_up_text_and_update(self._updadeQText.toPlainText(), 'FOME'))

    def set_fome_highlight(self):
        self._l_fome.setStyleSheet(ACTIVATED_CSS)

    def set_update_text_sede(self):
        self._updadeQText.setText(self.pick_up_text_and_update(self._updadeQText.toPlainText(), 'SEDE'))

    def set_sede_highlight(self):
        self._l_sede.setStyleSheet(ACTIVATED_CSS)

    def set_update_text_urinar(self):
        self._updadeQText.setText(self.pick_up_text_and_update(self._updadeQText.toPlainText(), 'URINAR'))

    def set_urinar_highlight(self):
        self._l_urinar.setStyleSheet(ACTIVATED_CSS)

    def set_update_text_ar(self):
        self._updadeQText.setText(self.pick_up_text_and_update(self._updadeQText.toPlainText(), 'AR'))

    def set_ar_highlight(self):
        self._l_ar.setStyleSheet(ACTIVATED_CSS_AR)

    def set_update_text_posicao(self):
        self._updadeQText.setText(self.pick_up_text_and_update(self._updadeQText.toPlainText(), 'POSIÇÃO'))

    def set_posicao_highlight(self):
        self._l_posicao.setStyleSheet(ACTIVATED_CSS)

    def set_all_down(self):
        self._l_sim.setStyleSheet(NORMAL_CSS)
        self._l_nao.setStyleSheet(NORMAL_CSS)
        self._l_fome.setStyleSheet(NORMAL_CSS)
        self._l_sede.setStyleSheet(NORMAL_CSS)
        self._l_urinar.setStyleSheet(NORMAL_CSS)
        self._l_ar.setStyleSheet(NORMAL_CSS_AR)
        self._l_posicao.setStyleSheet(NORMAL_CSS)

    def download_code(self):
        threading.Thread(target=self._asyncio_thread, args=(ASYNC_LOOP,)).start()

    async def get_one_code(self, tcp_client):
        serv_code = tcp_client.read_only_one_code_from_server()
        self.clear_button.click()
        t_sound = PlaySoundThread(thread_id=serv_code,
                                  name=serv_code,
                                  counter=int(serv_code),
                                  index_vec=int(serv_code))
        t_sound.start()
        self.decode_code(serv_code)
        if tcp_client.count - 1 in [0, EW_CONSTANT + 1, EW_CONSTANT * 2 + 2,
                                EW_CONSTANT * 3 + 3, EW_CONSTANT * 4 + 4,
                                EW_CONSTANT * 5 + 5, EW_CONSTANT * 6 + 6]:
            self.update_code_in_label(serv_code)
            await asyncio.sleep(1)
            self.clear_button.click()
        elif tcp_client.count - 1 in [EW_CONSTANT * 7 + 7,
                                EW_CONSTANT * 8 + 8, EW_CONSTANT * 9 + 9,
                                EW_CONSTANT * 10 + 10, EW_CONSTANT * 11 + 11,
                                EW_CONSTANT * 12 + 12, EW_CONSTANT * 13 + 13]:
            self.update_code_in_label(serv_code)
            await asyncio.sleep(1)
            self.clear_button.click()
        await asyncio.sleep(2)
        t_sound.join()
        return serv_code

    def check_aviability_func(self):
        print('aviability')

    def _asyncio_thread(self, async_loop):
        async_loop.run_until_complete(self.open_tcp_connections_and_enqueue())

    async def open_tcp_connections_and_enqueue(self):
        print("opening connection...")
        TCP_CLIENT.init_connection_with_server()
        print("connection ok!")
        tasks = [self.get_one_code(tcp_client=TCP_CLIENT) for num in range(999)]
        completed, pending = await asyncio.wait(tasks)
        results = [task.result() for task in completed]

    def decode_code(self, code):
        if code == 1:
            self.insert_code_1.click()
        elif code == 2:
            self.insert_code_2.click()
        elif code == 3:
            self.insert_code_3.click()
        elif code == 4:
            self.insert_code_4.click()
        elif code == 5:
            self.insert_code_5.click()
        elif code == 6:
            self.insert_code_6.click()
        elif code == 7:
            self.insert_code_7.click()
        else:
            print('unknown code received')
            self.set_all_down()
            print("error")
            exit(1)

    def update_code_in_label(self, code):
        self.clear_button.click()
        print('code inside update: {}'.format(code))
        if code == 1:
            self.insert_code_update_1.click()
        elif code == 2:
            self.insert_code_update_2.click()
        elif code == 3:
            self.insert_code_update_3.click()
        elif code == 4:
            self.insert_code_update_4.click()
        elif code == 5:
            self.insert_code_update_5.click()
        elif code == 6:
            self.insert_code_update_6.click()
        elif code == 7:
            self.insert_code_update_7.click()
        #time.sleep(1)
        self.clear_button.click()

    def closeEvent(self, event):
        close = QMessageBox.question(self,
                                               "QUIT",
                                               "Are you sure want to stop process?",
                                               QMessageBox.Yes | QMessageBox.No)
        if close == QMessageBox.Yes:
            event.accept()
            exit(-1)
        else:
            event.ignore



try:
    ap = QApplication(sys.argv)
    ap.setStyle('Fusion')
    ap.setStyleSheet('QApplication {background-color: black;}')
    dialog = QtSideGui()
    dialog.setStyleSheet('QtSideGui {background-color: black;}')
    dialog.show()
    sys.exit(ap.exec_())
except Exception as e:
    print(e)
    QMessageBox.information(ap, 'Information', 'An error has occurred.')


Do you haveany idea on how I can do this? Thank you very much

Upvotes: 0

Views: 2180

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

If you want to set the image using Qt Style Sheet then you should use background-image: url(/path/of/image);, and it is advisable to use the full path. If you want to change the image it is necessary to force it and for that you must use the unpolish() and polish() methods, in that order.

On the other hand if you want to change the Qt Style Sheet depending on the status of the widget then use a q-property.

I will not use the code you provide for obvious reasons, so in the following example I generate random numbers making a single QTextEdit active. On the other hand, the structure of the project is as follows:

├── images
│   ├── image1.png
│   └── image2.png
└── main.py
import os
import random
import itertools
from PyQt5 import QtCore, QtGui, QtWidgets


class TextEdit(QtWidgets.QTextEdit):
    def isActive(self):
        if not hasattr(self, "_activated"):
            self._activated = False
        return self._activated

    def setActive(self, v):
        if self.isActive() == v:
            return
        self._activated = v
        self.style().unpolish(self)
        self.style().polish(self)

    active = QtCore.pyqtProperty(bool, fget=isActive, fset=setActive)


current_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)))
image_dir = os.path.abspath(os.path.join(current_dir, "images"))

QSS = """
TextEdit[active="false"]{
    background-image: url(%s);
    background-repeat: no-repeat;
    background-position: center;
}
TextEdit[active="true"]{
    background-image: url(%s);  
    background-repeat: no-repeat;
    background-position: center;
}
""" % (
    os.path.join(image_dir, "image1.png").replace(os.path.sep, '/'),
    os.path.join(image_dir, "image2.png").replace(os.path.sep, '/'),
)


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)

        lay = QtWidgets.QGridLayout(self)
        self.m_textedits = []

        for r, c in itertools.product((1, 2, 3, 4), (1, 2)):
            te = TextEdit()
            lay.addWidget(te, r, c)
            self.m_textedits.append(te)

        timer = QtCore.QTimer(self, timeout=self.generate, interval=500)
        timer.start()

    def generate(self):
        i = random.randint(0, len(self.m_textedits) - 1)
        for j, te in enumerate(self.m_textedits):
            te.setActive(i == j)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    app.setStyleSheet(QSS)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

Upvotes: 2

Related Questions