自定义QListWidget中QLabel叠放失败,窗口空白求助
Fixing Blank Window & Implementing Overlapped QLabels in PyQt4 Custom Widget
Hey there! Let's get your custom chat list item working properly—no more blank windows, and your icon will sit neatly on top of the other labels like you want.
What was going wrong?
Your code had a couple of key issues causing the blank window:
- You created a nested
self.widgetinsideQCustomQWidgetbut never added it to the parent widget's layout, so it wasn't being rendered. - None of your QLabels had defined positions or layout management, so they weren't showing up even if the parent widget worked.
- The custom widget's size hint wasn't properly configured, so the QListWidgetItem couldn't display it correctly.
Modified Working Code
Here's the fixed version with comments explaining the key changes:
import sys from PyQt4 import QtGui, QtCore from PIL import Image, ImageOps from PIL.ImageQt import ImageQt class QCustomQWidget (QtGui.QWidget): def __init__ (self, parent = None): super(QCustomQWidget, self).__init__(parent) # Set base widget size (adjust as needed later) self.setMinimumSize(250, 80) # --- Chat Message Label (bottom layer) --- self.chatMessage = QtGui.QLabel(self) # Position: leave space on left for icon, top for username self.chatMessage.setGeometry(QtCore.QRect(60, 30, 190, 50)) font = QtGui.QFont() font.setFamily('Comic Sans MS') font.setPointSize(11) self.chatMessage.setFont(font) self.chatMessage.setStyleSheet(''' color: rgb(255, 0, 0); border: 1px solid #0089ff; border-top-right-radius: 20px; border-bottom-right-radius: 20px; border-bottom-left-radius: 20px; padding: 5px; ''') # --- Username Label (middle layer) --- self.userName = QtGui.QLabel(self) font = QtGui.QFont() font.setFamily('Arial Narrow') font.setBold(True) font.setPointSize(11) self.userName.setFont(font) # Align to top-left, leave space for icon self.userName.setGeometry(QtCore.QRect(60, 0, 190, 30)) self.userName.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) self.userName.setStyleSheet(''' color: rgb(255, 255, 255); background-color: #0089ff; border: 1px solid #0089ff; border-bottom: none; border-top-right-radius: 20px; border-top-left-radius: 20px; padding-left: 10px; ''') # --- Icon Label (top layer, overlaps other labels) --- self.iconQLabel = QtGui.QLabel(self) # Position icon at top-left, overlapping username/message labels self.iconQLabel.setGeometry(QtCore.QRect(5, 5, 60, 60)) self.iconQLabel.setScaledContents(True) # Auto-fit image to label size def chat_messages (self, text): self.chatMessage.setText(text) def setTextUp (self, text): self.userName.setText(text) def setIcon (self, imagePath): # Process avatar with mask (removed unnecessary file save step) mask = Image.open('Images\\Mask.png').convert('L') image = Image.open('Images\\pro.jpg') output = ImageOps.fit(image, mask.size, centering=(0.5, 0.5)) output.putalpha(mask) output.thumbnail((60, 60), Image.LANCZOS) output = output.convert('RGBA') # Convert PIL image to QPixmap directly qimage = ImageQt(output) pixmap = QtGui.QPixmap.fromImage(qimage) self.iconQLabel.setPixmap(pixmap) class exampleQMainWindow (QtGui.QMainWindow): def __init__ (self): super(exampleQMainWindow, self).__init__() self.showMaximized() self.myQListWidget = QtGui.QListWidget(self) # Add sample items for icon, name, message in [ ('pic.png', 'Alice', 'Hey there! How are you doing?'), ('pic.png', 'Bob', 'Just finished my project—super proud!')]: myQCustomQWidget = QCustomQWidget() myQCustomQWidget.setTextUp(name) myQCustomQWidget.chat_messages(message) myQCustomQWidget.setIcon(icon) # Set item size to match custom widget's minimum size myQListWidgetItem = QtGui.QListWidgetItem(self.myQListWidget) myQListWidgetItem.setSizeHint(myQCustomQWidget.minimumSize()) self.myQListWidget.addItem(myQListWidgetItem) self.myQListWidget.setItemWidget(myQListWidgetItem, myQCustomQWidget) # List widget tweaks self.myQListWidget.scrollToBottom() self.myQListWidget.setAutoScrollMargin(15) self.myQListWidget.setSelectionRectVisible(False) self.myQListWidget.setUniformItemSizes(True) # Keep items consistent self.setCentralWidget(self.myQListWidget) self.setMinimumSize(660, 500) app = QtGui.QApplication([]) window = exampleQMainWindow() window.show() sys.exit(app.exec_())
Key Changes Explained
- Removed nested
self.widget: All labels are now direct children ofQCustomQWidget, so they're properly rendered. - Explicit
geometryfor labels: This ensures the icon sits on top of the username and message labels (the icon has a higher z-index by default since it's created last). setScaledContents(True)for icon: Makes sure your avatar image fits perfectly inside the icon label without distortion.- Simplified
setIcon: Skipped saving the processed image to a file—directly converts the PIL image to a QPixmap for better performance. - Adjusted list widget settings: Set
setUniformItemSizes(True)to keep all list items looking consistent.
To change the colors, just modify the background-color and border values in the CSS style sheets for userName and chatMessage labels.
内容的提问来源于stack exchange,提问作者And3r50n 1
相关产品推荐
相关产品推荐

