def sizeHint(self, option, index): """ Returns the size needed to display the item in a QSize object. """ if index.column() == 3: starRating = StarRating(index.data()) return starRating.sizeHint() else: return QStyledItemDelegate.sizeHint(self, option, index)
def sizeHint(self, option, index): """ Returns the size needed to display the item in a QSize object. """ if index.column() == 6: starRating = StarRating(index.data()) return starRating.sizeHint() else: return QStyledItemDelegate.sizeHint(self, option, index)
def paint(self, painter, option, index): """ Paint the items in the table. If the item referred to by <index> is a StarRating, we handle the painting ourselves. For the other items, we let the base class handle the painting as usual. In a polished application, we'd use a better check than the column number to find out if we needed to paint the stars, but it works for the purposes of this example. """ if index.column() == 3: starRating = StarRating(index.data()) # If the row is currently selected, we need to make sure we # paint the background accordingly. if option.state & QStyle.State_Selected: # The original C++ example used option.palette.foreground() to # get the brush for painting, but there are a couple of # problems with that: # - foreground() is obsolete now, use windowText() instead # - more importantly, windowText() just returns a brush # containing a flat color, where sometimes the style # would have a nice subtle gradient or something. # Here we just use the brush of the painter object that's # passed in to us, which keeps the row highlighting nice # and consistent. painter.fillRect(option.rect, painter.brush()) # Now that we've painted the background, call starRating.paint() # to paint the stars. starRating.paint(painter, option.rect, option.palette) else: QStyledItemDelegate.paint(self, painter, option, index)
def __init__(self, parent=None): """ Initialize the editor object, making sure we can watch mouse events. """ super(StarEditor, self).__init__(parent) self.setMouseTracking(True) self.setAutoFillBackground(True) self.starRating = StarRating()
class StarEditor(QWidget): """ The custom editor for editing StarRatings. """ # A signal to tell the delegate when we've finished editing. editingFinished = Signal() def __init__(self, parent=None): """ Initialize the editor object, making sure we can watch mouse events. """ super(StarEditor, self).__init__(parent) self.setMouseTracking(True) self.setAutoFillBackground(True) self.starRating = StarRating() def sizeHint(self): """ Tell the caller how big we are. """ return self.starRating.sizeHint() def paintEvent(self, event): """ Paint the editor, offloading the work to the StarRating class. """ painter = QPainter(self) self.starRating.paint(painter, self.rect(), self.palette(), isEditable=True) def mouseMoveEvent(self, event): """ As the mouse moves inside the editor, track the position and update the editor to display as many stars as necessary. """ star = self.starAtPosition(event.x()) if (star != self.starRating.starCount) and (star != -1): self.starRating.starCount = star self.update() def mouseReleaseEvent(self, event): """ Once the user has clicked his/her chosen star rating, tell the delegate we're done editing. """ self.editingFinished.emit() def starAtPosition(self, x): """ Calculate which star the user's mouse cursor is currently hovering over. """ star = (x / (self.starRating.sizeHint().width() / self.starRating.maxStarCount)) + 1 if (star <= 0) or (star > self.starRating.maxStarCount): return -1 return star
def setEditorData(self, editor, index): """ Sets the data to be displayed and edited by our custom editor. """ if index.column() == 3: editor.starRating = StarRating(index.data()) else: QStyledItemDelegate.setEditorData(self, editor, index)
app = QApplication(sys.argv) # Create and populate the tableWidget tableWidget = QTableWidget(4, 4) tableWidget.setItemDelegate(StarDelegate()) tableWidget.setEditTriggers(QAbstractItemView.DoubleClicked | QAbstractItemView.SelectedClicked) tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) tableWidget.setHorizontalHeaderLabels( ["Title", "Genre", "Artist", "Rating"]) data = [["Mass in B-Minor", "Baroque", "J.S. Bach", 5], ["Three More Foxes", "Jazz", "Maynard Ferguson", 4], ["Sex Bomb", "Pop", "Tom Jones", 3], ["Barbie Girl", "Pop", "Aqua", 5]] for r in range(len(data)): tableWidget.setItem(r, 0, QTableWidgetItem(data[r][0])) tableWidget.setItem(r, 1, QTableWidgetItem(data[r][1])) tableWidget.setItem(r, 2, QTableWidgetItem(data[r][2])) item = QTableWidgetItem() item.setData(0, StarRating(data[r][3]).starCount) tableWidget.setItem(r, 3, item) tableWidget.resizeColumnsToContents() tableWidget.resize(500, 300) tableWidget.show() sys.exit(app.exec_())
def __init__(self, parent=None): QFrame.__init__(self, parent) self.setFixedSize(200, 300) self.setObjectName("Card") self.setAutoFillBackground(True) self.appId = -1 self.appIcon = "./img/card/bird.png" self.appBack = "./img/card/card_back.png" self.appName = "PROS Smart CPQ for Manufacturing" self.appDev = "By PROS\nWeb apps" self.appRating = 0 self.appFeedback = 0 self.appState = 0 self.style_str = "border: 1px solid #ddd; background: qlineargradient(spread:pad, x1:0 y1:0, x2:1 y2:1, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(225, 225, 225, 225));" self.appDesc = "Deliver Sales Automation and Profits Through Personalized Selling" self.setBackgroundImage(self.appBack) self.iconSize = 48, 48 self.iconMargins = 10, 10, 10, 10 self.iconFrameStyle = STYLES.STYLE_DEFAULT self.iconFrame = QLabel(self) self.iconFrame.setAutoFillBackground(True) self.iconFrame.setObjectName("IconFrame") self.iconFrame.setStyleSheet(self.iconFrameStyle) self.imgIcon = QLabel(self.iconFrame) self.imgIcon.setPixmap(QPixmap(self.appIcon)) self.imgIcon.setFixedSize(48, 48) self.imgIcon.setScaledContents(True) self.iconLayout = QHBoxLayout(self.iconFrame) self.iconLayout.setContentsMargins(10, 10, 10, 10) self.iconLayout.setAlignment(Qt.AlignLeft) self.iconLayout.addWidget(self.imgIcon, Qt.AlignLeft) self.iconFrame.setLayout(self.iconLayout) self.txtName = ElideLabel("", self) self.txtName.setText(self.appName) self.txtName.setFont(QFont("Roboto", 15)) self.txtName.setElideMode(1) self.txtName.setWordWrap(True) self.txtDev = ElideLabel("", self) self.txtDev.setWordWrap(True) self.txtDev.setText(self.appDev) self.txtDev.setFont(QFont("Roboto", 8)) self.txtDesc = ElideLabel("", self) self.txtDesc.setText(self.appDesc) self.txtDesc.setAlignment(Qt.AlignTop) self.txtDesc.setFont(QFont("Roboto", 10)) self.txtDesc.setElideMode(1) self.txtDesc.setWordWrap(True) self.starRating = StarRating(self) self.feedbackGiven = QLabel(self) self.feedbackGiven.setObjectName("Feedback") self.feedbackGiven.setStyleSheet("#Feedback{color: #ababab}") self.feedbackGiven.setFont(QFont("Roboto", 12)) self.feedbackGiven.setAlignment(Qt.AlignVCenter) self.feedbackGiven.setText("(" + str(self.appFeedback) + ")") self.btnInstall = Button('Install', self) self.btnInstall.clicked.connect(self.onInstallClicked) self.btnLaunch = Button('Launch', self) self.btnLaunch.setButtonType(Button.BUTTON_TYPE.LAUNCH) self.btnLaunch.clicked.connect(self.onLaunchClicked) self.btnLaunch.hide() self.btnUninstall = Button('Uninstall', self) self.btnUninstall.setButtonType(Button.BUTTON_TYPE.DELETE) self.btnUninstall.clicked.connect(self.onUninstallClicked) self.btnUninstall.hide() self.shadowEffect = QGraphicsDropShadowEffect(self) self.shadowEffect.setBlurRadius(9) self.shadowEffect.setColor(QColor(225, 225, 225)) self.shadowEffect.setOffset(5, 5) self.setGraphicsEffect(self.shadowEffect) self.frameLayout = QVBoxLayout(self) self.frameLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout = QVBoxLayout() self.mainLayout.setSpacing(5) self.mainLayout.setContentsMargins(10, 0, 10, 15) self.ratingLayout = QHBoxLayout() self.ratingLayout.setSpacing(5) self.ratingLayout.addWidget(self.starRating, 1, Qt.AlignLeft) self.ratingLayout.addWidget(self.feedbackGiven, 1, Qt.AlignLeft) self.separator = QFrame(self) self.separator.setObjectName("line") self.separator.setFixedHeight(2) self.separator.setFixedWidth(self.width()) self.separator.setFrameShape(QFrame.HLine) self.separator.setFrameShadow(QFrame.Sunken) self.btnLayout = QHBoxLayout() self.btnLayout.setContentsMargins(5, 5, 5, 10) self.btnLayout.setSpacing(20) self.btnLayout.setAlignment(Qt.AlignHCenter) self.btnLayout.addWidget(self.btnInstall) self.btnLayout.addWidget(self.btnUninstall) self.btnLayout.addWidget(self.btnLaunch) self.mainLayout.addWidget(self.txtName, 1, Qt.AlignLeft) self.mainLayout.addWidget(self.txtDev, 1, Qt.AlignLeft) self.mainLayout.addWidget(self.txtDesc, 3, Qt.AlignLeft) self.mainLayout.addLayout(self.ratingLayout, Qt.AlignLeft) self.frameLayout.addWidget(self.iconFrame, 1) self.frameLayout.addLayout(self.mainLayout) self.frameLayout.addWidget(self.separator) self.frameLayout.addLayout(self.btnLayout) self.setLayout(self.frameLayout) self.setAppState(self.appState) self.show()
class AppCard(QFrame): """A Card widget derived from QFrame contains app icon, app name, app developer, app description, app rating, etc""" STYLES = STYLES Q_ENUM(STYLES) def __init__(self, parent=None): QFrame.__init__(self, parent) self.setFixedSize(200, 300) self.setObjectName("Card") self.setAutoFillBackground(True) self.appId = -1 self.appIcon = "./img/card/bird.png" self.appBack = "./img/card/card_back.png" self.appName = "PROS Smart CPQ for Manufacturing" self.appDev = "By PROS\nWeb apps" self.appRating = 0 self.appFeedback = 0 self.appState = 0 self.style_str = "border: 1px solid #ddd; background: qlineargradient(spread:pad, x1:0 y1:0, x2:1 y2:1, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(225, 225, 225, 225));" self.appDesc = "Deliver Sales Automation and Profits Through Personalized Selling" self.setBackgroundImage(self.appBack) self.iconSize = 48, 48 self.iconMargins = 10, 10, 10, 10 self.iconFrameStyle = STYLES.STYLE_DEFAULT self.iconFrame = QLabel(self) self.iconFrame.setAutoFillBackground(True) self.iconFrame.setObjectName("IconFrame") self.iconFrame.setStyleSheet(self.iconFrameStyle) self.imgIcon = QLabel(self.iconFrame) self.imgIcon.setPixmap(QPixmap(self.appIcon)) self.imgIcon.setFixedSize(48, 48) self.imgIcon.setScaledContents(True) self.iconLayout = QHBoxLayout(self.iconFrame) self.iconLayout.setContentsMargins(10, 10, 10, 10) self.iconLayout.setAlignment(Qt.AlignLeft) self.iconLayout.addWidget(self.imgIcon, Qt.AlignLeft) self.iconFrame.setLayout(self.iconLayout) self.txtName = ElideLabel("", self) self.txtName.setText(self.appName) self.txtName.setFont(QFont("Roboto", 15)) self.txtName.setElideMode(1) self.txtName.setWordWrap(True) self.txtDev = ElideLabel("", self) self.txtDev.setWordWrap(True) self.txtDev.setText(self.appDev) self.txtDev.setFont(QFont("Roboto", 8)) self.txtDesc = ElideLabel("", self) self.txtDesc.setText(self.appDesc) self.txtDesc.setAlignment(Qt.AlignTop) self.txtDesc.setFont(QFont("Roboto", 10)) self.txtDesc.setElideMode(1) self.txtDesc.setWordWrap(True) self.starRating = StarRating(self) self.feedbackGiven = QLabel(self) self.feedbackGiven.setObjectName("Feedback") self.feedbackGiven.setStyleSheet("#Feedback{color: #ababab}") self.feedbackGiven.setFont(QFont("Roboto", 12)) self.feedbackGiven.setAlignment(Qt.AlignVCenter) self.feedbackGiven.setText("(" + str(self.appFeedback) + ")") self.btnInstall = Button('Install', self) self.btnInstall.clicked.connect(self.onInstallClicked) self.btnLaunch = Button('Launch', self) self.btnLaunch.setButtonType(Button.BUTTON_TYPE.LAUNCH) self.btnLaunch.clicked.connect(self.onLaunchClicked) self.btnLaunch.hide() self.btnUninstall = Button('Uninstall', self) self.btnUninstall.setButtonType(Button.BUTTON_TYPE.DELETE) self.btnUninstall.clicked.connect(self.onUninstallClicked) self.btnUninstall.hide() self.shadowEffect = QGraphicsDropShadowEffect(self) self.shadowEffect.setBlurRadius(9) self.shadowEffect.setColor(QColor(225, 225, 225)) self.shadowEffect.setOffset(5, 5) self.setGraphicsEffect(self.shadowEffect) self.frameLayout = QVBoxLayout(self) self.frameLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout = QVBoxLayout() self.mainLayout.setSpacing(5) self.mainLayout.setContentsMargins(10, 0, 10, 15) self.ratingLayout = QHBoxLayout() self.ratingLayout.setSpacing(5) self.ratingLayout.addWidget(self.starRating, 1, Qt.AlignLeft) self.ratingLayout.addWidget(self.feedbackGiven, 1, Qt.AlignLeft) self.separator = QFrame(self) self.separator.setObjectName("line") self.separator.setFixedHeight(2) self.separator.setFixedWidth(self.width()) self.separator.setFrameShape(QFrame.HLine) self.separator.setFrameShadow(QFrame.Sunken) self.btnLayout = QHBoxLayout() self.btnLayout.setContentsMargins(5, 5, 5, 10) self.btnLayout.setSpacing(20) self.btnLayout.setAlignment(Qt.AlignHCenter) self.btnLayout.addWidget(self.btnInstall) self.btnLayout.addWidget(self.btnUninstall) self.btnLayout.addWidget(self.btnLaunch) self.mainLayout.addWidget(self.txtName, 1, Qt.AlignLeft) self.mainLayout.addWidget(self.txtDev, 1, Qt.AlignLeft) self.mainLayout.addWidget(self.txtDesc, 3, Qt.AlignLeft) self.mainLayout.addLayout(self.ratingLayout, Qt.AlignLeft) self.frameLayout.addWidget(self.iconFrame, 1) self.frameLayout.addLayout(self.mainLayout) self.frameLayout.addWidget(self.separator) self.frameLayout.addLayout(self.btnLayout) self.setLayout(self.frameLayout) self.setAppState(self.appState) self.show() #automatically adjust child widgets' sizes based on the frame's geometry #this might affect widgets' sizes def autoAdjust(self): self.starRating.adjustWidthByHeight(self.height()/15) self.feedbackGiven.setFixedHeight(self.height()/16) self.iconFrame.setFixedHeight(self.height()/5) self.setIconSize(self.iconFrame.height() * 4 / 5, self.iconFrame.height() *4 / 5) mm = self.iconFrame.height() / (5 * 2) self.setIconMargins(mm, mm, mm, mm) #set fixed size for the icon, maybe called logo or brand def setIconSize(self, aw, ah): self.iconSize = aw, ah self.imgIcon.setFixedSize(self.iconSize[0], self.iconSize[1]) #set icon margins within the icon frame def setIconMargins(self, ml, mt = 0, mr = 0, mb = 0): self.iconMargins = ml, mt, mr, mb mml, mmt, mmr, mmb = self.mainLayout.getContentsMargins() self.iconLayout.setContentsMargins(mml, mt, mmr, mb) #set icon frame's style, you can stylize background(single color, gradient or image), border, etc def setIconFrameStyle(self, style): self.iconFrameStyle = style self.iconFrame.setStyleSheet(self.iconFrameStyle) @pyqtSlot() def onInstallClicked(self): QMessageBox.information(None, "ID: " + str(self.appId), "Install button clicked") @pyqtSlot() def onUninstallClicked(self): QMessageBox.information(None, "ID: " + str(self.appId), "Gonna uninstall the app?") @pyqtSlot() def onLaunchClicked(self): QMessageBox.information(None, "ID: " + str(self.appId), "Launch is not ready yet!") #set whether the app is already installed or not, accordingly show or hide appropriate buttons def setAppState(self, state): if state == 0: self.btnInstall.show() self.btnUninstall.hide() self.btnLaunch.hide() elif state == 1: self.btnInstall.hide() self.btnUninstall.show() self.btnLaunch.show() self.autoAdjust() #return current app state def getAppState(self): return self.appState #set applicaton name def setAppName(self, name): if name != self.appName: self.appName = name self.txtName.setText(self.appName) #return application name def getAppName(self): return self.appName #set developer name, or could be company name def setAppDevName(self, name): if name != self.appDev: self.appDev = name self.txtDev.setText(self.appDev) #return developer name def getAppDevName(self): return self.appDev #set description about application def setAppDesc(self, desc): if desc != self.appDesc: self.appDesc = desc self.txtDesc.setText(self.appDesc) #return description of application def getAppDesc(self): return self.appDesc #set application icon with appropriate file path def setAppIcon(self, imgPath): if imgPath != self.appIcon: self.appIcon = imgPath self.imgIcon.setPixmap(QPixmap(self.appIcon)) #return QPixmap of icon def getAppIconPixmap(self): return QPixmap(self.appIcon) #return path to icon def getAppIconPath(self): return self.appIcon #set applicaiton star rating and count of given feedbacks def setAppRating(self, rating, feedback): if rating != self.appRating or feedback != self.appFeedback: self.appRating, self.appFeedback = rating, feedback self.starRating.setRating(rating) self.feedbackGiven.setText("(" + str(feedback) + ")") #return star rating value and the count of given feedbacks def getAppRating(self): return (self.appRating, self.appFeedback) #set path to background would be embedded into stylesheet string def setBackgroundImage(self, img): self.appBack = img self.setStyleSheet("#Card{" + self.style_str + " background-image: url(" + self.appBack + ")}") #set application ID def setAppId(self, id): self.appId = id #return app ID def getAppId(self): return self.appId #set blur radius of frame's shadow effect def setShadowBlurRadius(self, radius): self.shadowEffect.setBlurRadius(radius) #set shadow offset of frame's shadow effect def setShadowOffset(self, offX, offY): self.shadowEffect.setOffset(offX, offY) #set shadow color of frame's shadow effect def setShadowColor(self, color): self.shadowEffect.setColor(color) #set font of application name def setAppNameFont(self, font): self.txtName.setFont(font) #set font of developer name def setAppDevFont(self, font): self.txtDev.setFont(font) #set font of description to the app def setAppDescFont(self, font): self.txtDesc.setFont(font);
def __init__(self, parent=None): super().__init__(parent) self.mShowAll = False self.mRatingFrame = QFrame(self) self.mRatingFrame.setFixedWidth(200) self.mRating = StarRating(self.mRatingFrame) self.mRating.adjustWidthByHeight(21) self.mRatedDate = QLabel("Sat, Jun 17, 2017", self.mRatingFrame) self.mRatedDate.setFont(QFont("SegeoUI", 12, QFont.Light)) self.mRater = QLabel("Anonymous", self.mRatingFrame) self.mRater.setFont(QFont("SegeoUI", 12, QFont.Light)) self.mRatingLayout = QVBoxLayout(self.mRatingFrame) self.mRatingLayout.setContentsMargins(10, 5, 10, 5) self.mRatingLayout.setAlignment(Qt.AlignTop) self.mRatingLayout.setSpacing(15) self.mRatingLayout.addWidget(self.mRating, 0, Qt.AlignLeft | Qt.AlignTop) self.mRatingLayout.addWidget(self.mRatedDate, 0, Qt.AlignLeft | Qt.AlignTop) self.mRatingLayout.addWidget(self.mRater, 0, Qt.AlignLeft | Qt.AlignTop) self.mTxtFrame = QFrame(self) self.mTitle = ElideLabel(self.mTxtFrame, "Undefined") self.mTitle.setContentsMargins(0, 0, 0, 0) self.mTitle.setFont(QFont("SegeoUI", 14, QFont.Light)) self.mComment = AutoTextView(self.mTxtFrame) self.mComment.setFont(QFont("SegeoUI", 12, QFont.Light)) self.mComment.lessThanLimit.connect(self.onLessThanLimit) self.mComment.moreThanLimit.connect(self.onMoreThanLimit) self.mComment.setAutoFillBackground(True) self.mBtnMore = Link(self.mTxtFrame, "Read More") self.mBtnMore.setHoverColor("rgba(25, 55, 155, 255);") self.mBtnMore.setHoverStyle("") self.mBtnMore.setFont(QFont("SegeoUI", 12, QFont.Light)) self.mBtnMore.setContentsMargins(0, 0, 0, 0) self.mBtnMore.clicked.connect(self.onReadMore) self.mBtnReport = Link(self.mTxtFrame, "Report this review") self.mBtnReport.setDefaultColor("rgba(0, 0, 0, 255);") self.mBtnReport.clicked.connect(self.onReport) self.mCaptionLayout = QHBoxLayout() self.mCaptionLayout.setContentsMargins(0, 0, 0, 0) self.mCaptionLayout.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.mCaptionLayout.addWidget(self.mTitle) self.mTxtLayout = QVBoxLayout(self.mTxtFrame) self.mTxtLayout.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.mTxtLayout.setContentsMargins(5, 5, 5, 5) self.mTxtLayout.setSpacing(5) self.mTxtLayout.addLayout(self.mCaptionLayout, 0) self.mTxtLayout.addWidget(self.mComment) self.mTxtLayout.addWidget(self.mBtnMore, 0, Qt.AlignLeft | Qt.AlignTop) self.mTxtLayout.addWidget(self.mBtnReport, 0, Qt.AlignLeft | Qt.AlignTop) self.mLayout = QHBoxLayout(self) self.mLayout.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.mLayout.addWidget(self.mRatingFrame) self.mLayout.addWidget(self.mTxtFrame) self.setObjectName("ReviewCard")
class ReviewCard(QFrame): """ Review Card widget derived from QFrame which contains star rating, reviewed date, reviewer, title, comment and two text buttons""" def __init__(self, parent=None): super().__init__(parent) self.mShowAll = False self.mRatingFrame = QFrame(self) self.mRatingFrame.setFixedWidth(200) self.mRating = StarRating(self.mRatingFrame) self.mRating.adjustWidthByHeight(21) self.mRatedDate = QLabel("Sat, Jun 17, 2017", self.mRatingFrame) self.mRatedDate.setFont(QFont("SegeoUI", 12, QFont.Light)) self.mRater = QLabel("Anonymous", self.mRatingFrame) self.mRater.setFont(QFont("SegeoUI", 12, QFont.Light)) self.mRatingLayout = QVBoxLayout(self.mRatingFrame) self.mRatingLayout.setContentsMargins(10, 5, 10, 5) self.mRatingLayout.setAlignment(Qt.AlignTop) self.mRatingLayout.setSpacing(15) self.mRatingLayout.addWidget(self.mRating, 0, Qt.AlignLeft | Qt.AlignTop) self.mRatingLayout.addWidget(self.mRatedDate, 0, Qt.AlignLeft | Qt.AlignTop) self.mRatingLayout.addWidget(self.mRater, 0, Qt.AlignLeft | Qt.AlignTop) self.mTxtFrame = QFrame(self) self.mTitle = ElideLabel(self.mTxtFrame, "Undefined") self.mTitle.setContentsMargins(0, 0, 0, 0) self.mTitle.setFont(QFont("SegeoUI", 14, QFont.Light)) self.mComment = AutoTextView(self.mTxtFrame) self.mComment.setFont(QFont("SegeoUI", 12, QFont.Light)) self.mComment.lessThanLimit.connect(self.onLessThanLimit) self.mComment.moreThanLimit.connect(self.onMoreThanLimit) self.mComment.setAutoFillBackground(True) self.mBtnMore = Link(self.mTxtFrame, "Read More") self.mBtnMore.setHoverColor("rgba(25, 55, 155, 255);") self.mBtnMore.setHoverStyle("") self.mBtnMore.setFont(QFont("SegeoUI", 12, QFont.Light)) self.mBtnMore.setContentsMargins(0, 0, 0, 0) self.mBtnMore.clicked.connect(self.onReadMore) self.mBtnReport = Link(self.mTxtFrame, "Report this review") self.mBtnReport.setDefaultColor("rgba(0, 0, 0, 255);") self.mBtnReport.clicked.connect(self.onReport) self.mCaptionLayout = QHBoxLayout() self.mCaptionLayout.setContentsMargins(0, 0, 0, 0) self.mCaptionLayout.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.mCaptionLayout.addWidget(self.mTitle) self.mTxtLayout = QVBoxLayout(self.mTxtFrame) self.mTxtLayout.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.mTxtLayout.setContentsMargins(5, 5, 5, 5) self.mTxtLayout.setSpacing(5) self.mTxtLayout.addLayout(self.mCaptionLayout, 0) self.mTxtLayout.addWidget(self.mComment) self.mTxtLayout.addWidget(self.mBtnMore, 0, Qt.AlignLeft | Qt.AlignTop) self.mTxtLayout.addWidget(self.mBtnReport, 0, Qt.AlignLeft | Qt.AlignTop) self.mLayout = QHBoxLayout(self) self.mLayout.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.mLayout.addWidget(self.mRatingFrame) self.mLayout.addWidget(self.mTxtFrame) self.setObjectName("ReviewCard") @pyqtSlot() def onLessThanLimit(self): self.mBtnMore.hide() @pyqtSlot() def onMoreThanLimit(self): self.mBtnMore.show() def setReviewRating(self, rating): self.mRating.setRating(float(rating)) # set rated text with formatted QDateTime variable def setReviewDate(self, date): self.mRatedDate.setText(date.toString("ddd, MMM d, yyyy")) # set rated text with pure string def setReviewDateString(self, str): self.mRatedDate.setText(str) def setReviewTitle(self, str): self.mTitle.setText(str) def setReviewComment(self, str): self.mComment.setText(str) def showComment(self, showAll=False): if showAll: self.mComment.showAll() self.mBtnMore.setText("Read Less") else: self.mComment.showLess() self.mBtnMore.setText("Read More") def onReadMore(self): self.mShowAll = not self.mShowAll self.showComment(self.mShowAll) def onReport(self): QMessageBox.information(self, "", "User reported the review")
def __init__(self, parent=None): super().__init__(parent) self.mIsPressed = False self.mStar = StarRating(self) self.mStar.setClickable(True) self.mStar.adjustWidthByHeight(25) self.separator = QFrame(self) self.separator.setObjectName("Separator") self.separator.setFixedHeight(2) self.separator.setFrameShape(QFrame.HLine) self.separator.setFrameShadow(QFrame.Sunken) self.mTitleEdit = QLineEdit(self) self.mTitleEdit.setObjectName("BriefEdit") self.mTitleEdit.setStyleSheet( "#BriefEdit{border: 1px solid lightgrey;}") self.mTitleEdit.setPlaceholderText("Title") self.mTitleEdit.setFont(QFont("SegeoUI", 12)) self.mTitleEdit.textChanged.connect(self.onTitleChanged) self.mTitleWarning = QLabel(self) self.mTitleWarning.setObjectName("BriefWarning") self.mTitleWarning.setStyleSheet( "#BriefWarning{border: none; color: red; background: transparent;}" ) self.mTitleWarning.setText("This field is required!") self.mTitleWarning.hide() self.mComment = QTextEdit(self) self.mComment.setPlaceholderText("Comment") self.mComment.setObjectName("DescEdit") self.mComment.setStyleSheet("#DescEdit{border: 1px solid lightgrey}") self.mComment.setFont(QFont("SegeoUI", 10, QFont.Light)) self.mTextLayout = QVBoxLayout() self.mTextLayout.setContentsMargins(0, 0, 0, 0) self.mTextLayout.setSpacing(5) self.mTextLayout.addWidget(self.mTitleWarning) self.mTextLayout.addWidget(self.mTitleEdit) self.mTextLayout.addWidget(self.mComment) self.mBtnSubmit = ReviewButton(self, "Submit") self.mBtnSubmit.setFixedWidth(150) self.mBtnSubmit.clicked.connect(self.accept) self.mBtnClose = CloseButton(self) self.mBtnClose.setFixedWidth(self.mBtnClose.height()) self.mBtnClose.clicked.connect(self.reject) self.mBtnClose.setGeometry(self.width() - self.mBtnClose.width() - 1, 1, self.mBtnClose.width(), self.mBtnClose.height()) self.mBtnLayout = QHBoxLayout() self.mBtnLayout.setContentsMargins(30, 10, 30, 20) self.mBtnLayout.addWidget(self.mBtnSubmit) self.mLayout = QVBoxLayout(self) self.mLayout.setContentsMargins(10, 20, 10, 10) self.mLayout.setSpacing(20) self.mLayout.addWidget(self.mStar, 0, Qt.AlignCenter) self.mLayout.addWidget(self.separator) self.mLayout.addLayout(self.mTextLayout) self.mLayout.addLayout(self.mBtnLayout) self.setWindowFlags(Qt.FramelessWindowHint) self.setFixedSize(400, 400) self.setObjectName("SubmitDialog") self.setStyleSheet( "#SubmitDialog{border: 1px solid lightgrey; background-color: white;}" )
class SubmitDialog(MovableDialog): def __init__(self, parent=None): super().__init__(parent) self.mIsPressed = False self.mStar = StarRating(self) self.mStar.setClickable(True) self.mStar.adjustWidthByHeight(25) self.separator = QFrame(self) self.separator.setObjectName("Separator") self.separator.setFixedHeight(2) self.separator.setFrameShape(QFrame.HLine) self.separator.setFrameShadow(QFrame.Sunken) self.mTitleEdit = QLineEdit(self) self.mTitleEdit.setObjectName("BriefEdit") self.mTitleEdit.setStyleSheet( "#BriefEdit{border: 1px solid lightgrey;}") self.mTitleEdit.setPlaceholderText("Title") self.mTitleEdit.setFont(QFont("SegeoUI", 12)) self.mTitleEdit.textChanged.connect(self.onTitleChanged) self.mTitleWarning = QLabel(self) self.mTitleWarning.setObjectName("BriefWarning") self.mTitleWarning.setStyleSheet( "#BriefWarning{border: none; color: red; background: transparent;}" ) self.mTitleWarning.setText("This field is required!") self.mTitleWarning.hide() self.mComment = QTextEdit(self) self.mComment.setPlaceholderText("Comment") self.mComment.setObjectName("DescEdit") self.mComment.setStyleSheet("#DescEdit{border: 1px solid lightgrey}") self.mComment.setFont(QFont("SegeoUI", 10, QFont.Light)) self.mTextLayout = QVBoxLayout() self.mTextLayout.setContentsMargins(0, 0, 0, 0) self.mTextLayout.setSpacing(5) self.mTextLayout.addWidget(self.mTitleWarning) self.mTextLayout.addWidget(self.mTitleEdit) self.mTextLayout.addWidget(self.mComment) self.mBtnSubmit = ReviewButton(self, "Submit") self.mBtnSubmit.setFixedWidth(150) self.mBtnSubmit.clicked.connect(self.accept) self.mBtnClose = CloseButton(self) self.mBtnClose.setFixedWidth(self.mBtnClose.height()) self.mBtnClose.clicked.connect(self.reject) self.mBtnClose.setGeometry(self.width() - self.mBtnClose.width() - 1, 1, self.mBtnClose.width(), self.mBtnClose.height()) self.mBtnLayout = QHBoxLayout() self.mBtnLayout.setContentsMargins(30, 10, 30, 20) self.mBtnLayout.addWidget(self.mBtnSubmit) self.mLayout = QVBoxLayout(self) self.mLayout.setContentsMargins(10, 20, 10, 10) self.mLayout.setSpacing(20) self.mLayout.addWidget(self.mStar, 0, Qt.AlignCenter) self.mLayout.addWidget(self.separator) self.mLayout.addLayout(self.mTextLayout) self.mLayout.addLayout(self.mBtnLayout) self.setWindowFlags(Qt.FramelessWindowHint) self.setFixedSize(400, 400) self.setObjectName("SubmitDialog") self.setStyleSheet( "#SubmitDialog{border: 1px solid lightgrey; background-color: white;}" ) #QDialog.accept, check whether everything is okay and close the dialog successfully def accept(self): if len(self.mTitleEdit.text()) < 1: self.mTitleWarning.show() self.mTitleEdit.setFocus() return QDialog.accept(self) #hide warning for title if there's any user input def onTitleChanged(self): if self.mTitleWarning.isVisible(): self.mTitleWarning.hide() #set geometry of close button when resize event is activated def resizeEvent(self, event): self.mBtnClose.setGeometry(self.width() - self.mBtnClose.width() - 1, 1, self.mBtnClose.width(), self.mBtnClose.height()) #return the whole information of dialog , rating, title and comment def getReviewInformation(self): return (self.mStar.getRating(), self.mTitleEdit.text(), self.mComment.toPlainText())