如何在 QTextEdit 中插入图像?
Posted
技术标签:
【中文标题】如何在 QTextEdit 中插入图像?【英文标题】:How can I insert an image in a QTextEdit? 【发布时间】:2019-11-08 08:16:10 【问题描述】:所以我试图在 Qtexteditor 上插入图像,到目前为止我只设法将 Qtexteditor 变成全白,我尝试了这个:
ACTIVATED_CSS = 'QTextEdit image: url(einstein.jpg);'
所以我以随机顺序接收一些从 1 到 7 的数字(通过 TCP),当代码接收到它们时,相应的 Qtexteditor 会以绿色背景“点亮”,但现在我想更改为图像点亮。
这是我的代码:
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.')
您对我如何做到这一点有任何想法吗?非常感谢
【问题讨论】:
【参考方案1】:如果您想使用 Qt 样式表设置图像,那么您应该使用background-image: url(/path/of/image);
,并且建议使用完整路径。如果您想更改图像,则必须强制它,为此您必须按顺序使用unpolish()
和polish()
方法。
另一方面,如果您想根据小部件的状态更改 Qt 样式表,请使用 q-property。
出于显而易见的原因,我不会使用您提供的代码,因此在以下示例中,我生成随机数,使单个 QTextEdit 处于活动状态。另一方面,项目的结构如下:
├── 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_())
【讨论】:
我试过你的代码,但所有的 TextEdit 都显示纯白色@eyllanesc @FranciscaMachado 您是否将图像“image1.png”和“image2.png”放在 .py 文件一侧的“images”文件夹中?如果有,image_dir
的值是多少?
是的,我做了,images_dir 是:'C:\\Users\\meca\\Desktop\\images' @eyllanesc
尝试我的更新,Qt 使用 unix 分隔符“/”,但 python 使用“\\”产生不兼容。以上是关于如何在 QTextEdit 中插入图像?的主要内容,如果未能解决你的问题,请参考以下文章