I want to keep the selected text keep the blue background color,but when i right clicked the text to generate a menu,the selected text will turn gray.how should i do. when i clicked the qlabel text to make it selected,the result is like this picture. And when i right click the selected text,the blue color turn gray. here is my demo code.
import pyperclip
import sys
from PySide2.QtCore import Qt
from PySide2.QtGui import QCursor
from PySide2.QtWidgets import QLabel,QMenu,QAction,QHBoxLayout,QApplication,QWidget
class moreInfoLabel(QLabel):
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
self.setTextInteractionFlags(Qt.TextSelectableByMouse)
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.rightMenuShow)#开放右键策略
self.setStyleSheet('''
QMenu {
border: Opx;
font-size: 9pt;
width:100px;
background-color:white
}
QMenu::item {
width:160px;
font-family: "Microsoft YaHei";
border: 0px;
min-height: 15px;
max-height: 26px;
padding:10px 15px 10px 15px;
font-size: 9pt;
}
QMenu::item:selected {
background-color: #f9f9f9;
}
QLabel{
font-size:13px;
font-family:微软雅黑;
}
''')
def rightMenuShow(self, pos):
print(self)
menu = QMenu(self)
menu.addAction(QAction('复制', menu))
menu.addAction(QAction('全选', menu))
menu.triggered.connect(self.menuSlot)
menu.exec_(QCursor.pos())
self.setStyleSheet('''
QMenu {
border: Opx;
font-size: 9pt;
width:100px;
background-color:white
}
QMenu::item {
width:160px;
font-family: "Microsoft YaHei";
border: 0px;
min-height: 15px;
max-height: 26px;
padding:10px 15px 10px 15px;
font-size: 9pt;
}
QMenu::item:selected {
background-color: #f9f9f9;
}
QLabel{
font-size:13px;
font-family:微软雅黑;
background-color: #f9f9f9;
}
''')
def menuSlot(self, act):
if act.text() == '复制':
pyperclip.copy(self.selectedText())
elif act.text() == '全选':
len1 = len(self.text())
self.setSelection(0,len1)
self.selectedText = self.text
class Demo(QWidget):
def __init__(self):
super(Demo, self).__init__()
self.moreinfo = moreInfoLabel("YOUJIAN")
self.layout = QHBoxLayout()
self.layout.addWidget(self.moreinfo)
self.setLayout(self.layout)
if __name__ == "__main__":
app = QApplication()
demo = Demo()
demo.show()
sys.exit(app.exec_())
Is there any way to solve this problem
When the menu is shown, the widget uses the Inactive
color group of the palette, which is the one normally used when the widget is in a window that is not active.
The simple solution is to temporarily replace the Highlight
and HighlightedText
color role for that group and restore the original palette afterwards. This step is necessary for consistency, as the default Inactive
colors should be kept in case the window is actually unfocused.
Note that in the following example I did some changes:
contextMenuEvent()
handler;self.selectedText
with self.text
, otherwise self.selectedText()
will always return the full text of the label, even if there is no selection;class MoreInfoLabel(QLabel):
_defaultPalette = None
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setTextInteractionFlags(Qt.TextSelectableByMouse|Qt.TextEditable)
self.setStyleSheet('''
QMenu {
border: Opx;
font-size: 9pt;
width:100px;
background-color:white
}
QMenu::item {
width:160px;
font-family: "Microsoft YaHei";
border: 0px;
min-height: 15px;
max-height: 26px;
padding:10px 15px 10px 15px;
font-size: 9pt;
}
QMenu::item:selected {
background-color: #f9f9f9;
}
QLabel{
font-size:13px;
font-family:微软雅黑;
}
''')
def contextMenuEvent(self, event):
oldPalette = self.palette()
tempPalette = self.palette()
tempPalette.setBrush(tempPalette.Inactive, tempPalette.Highlight,
oldPalette.highlight())
tempPalette.setBrush(tempPalette.Inactive, tempPalette.HighlightedText,
oldPalette.highlightedText())
self.setPalette(tempPalette)
menu = QMenu(self)
copyAction = menu.addAction('复制')
selectAction = menu.addAction('全选')
res = menu.exec_(event.globalPos())
self.setPalette(oldPalette)
if res == copyAction:
QApplication.clipboard().setText(self.selectedText())
elif res == selectAction:
self.setSelection(0, len(self.text()))
That said, QLabel already provides the menu entries you're trying to replace. If you did that for localization purposes, then overriding the default menu behavior is just wrong, as the problem is elsewhere.