I have added some check-able QListWidgetItem and I have challenge setting the border color for the checkboxes. setForeground function only sets the color of the checkbox text.
Any suggestion please.
This is my sample code creating the check-able QListWidgetItems:
watch_list = ["Protesters", "Local news staff", "Techfluencers"]
for category in watch_list:
self.checkBox = QtWidgets.QListWidgetItem(category)
self.checkBox.setFlags(self.checkBox.flags() | QtCore.Qt.ItemIsUserCheckable)
self.checkBox.setCheckState(QtCore.Qt.Unchecked)
self.checkBox.setForeground(QtGui.QColor('#FFFFFF'))
self.watchListslistWidget.addItem(self.checkBox)
I have tried
self.watchListslistWidget.setStyleSheet("""
QListWidget::item {
border:1px #FFFFFF
}
""")
But it sets the all background of the QListWidget to white.
You can use a delegate:
from PyQt5 import QtCore, QtGui, QtWidgets
class CheckBoxDelegate(QtWidgets.QStyledItemDelegate):
def initStyleOption(self, option, index):
super().initStyleOption(option, index)
option.palette.setBrush(QtGui.QPalette.Button, QtGui.QColor("red"))
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.watchListslistWidget = QtWidgets.QListWidget()
self.setCentralWidget(self.watchListslistWidget)
watch_list = ["Protesters", "Local news staff", "Techfluencers"]
for category in watch_list:
checkBox = QtWidgets.QListWidgetItem(category)
checkBox.setFlags(checkBox.flags() | QtCore.Qt.ItemIsUserCheckable)
checkBox.setCheckState(QtCore.Qt.Unchecked)
self.watchListslistWidget.addItem(checkBox)
delegate = CheckBoxDelegate(self.watchListslistWidget)
self.watchListslistWidget.setItemDelegate(delegate)
def main():
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
I got it working by using indicator as follows:
self.watchListslistWidget.setStyleSheet("""
QListWidget::indicator{
border: 1px solid white;
}
""")
Related
In my app I'm displaying a list using the QListwidget (I can't use other widget for this task), but I was wondering if it is possible to add to each item of the list a button since I'd like to create a delete item button. Basically I'd need something like this:
So I'd need to know how to create this button for each item in the list and a way to know which button is pressed.
This is my code right now:
import sys
from PyQt5.QtWidgets import (
QApplication,
QHBoxLayout,
QVBoxLayout,
QGroupBox,
QListWidget,
QWidget,
)
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("List Item with button")
self.centralwidgetHorizontalLayout = QHBoxLayout(self)
self.Frame = QGroupBox()
self.FrameHorizontalLayout = QHBoxLayout(self.Frame)
self.ListWidget = QListWidget(self.Frame)
self.ListWidget.setSpacing(11)
self.ListWidget.setStyleSheet(
"QListWidget { background: palette(window); border: none;}"
"QListWidget::item {"
"border-style: solid;"
"border-width:1px;"
"border-color: black;"
"margin-right: 30px;"
"}"
"QListWidget::item:hover {"
"border-color: green;"
"}")
self.FrameHorizontalLayout.addWidget(self.ListWidget)
self.centralwidgetHorizontalLayout.addWidget(self.Frame)
for i in range(13):
self.ListWidget.addItem(f"Line {i+1}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
window.showMaximized()
sys.exit(app.exec_())
Is there a way to accomplish this?
Just change the for code and the rest remains the same.
This is an example, should be what you want.
Typesetting solves it yourself.
class Window(QWidget):
def __init__(self):
...
for i in range(13):
item = QListWidgetItem()
item_widget = QWidget()
line_text = QLabel("I love PyQt!")
line_push_button = QPushButton("Push Me")
line_push_button.setObjectName(str(i))
line_push_button.clicked.connect(self.clicked)
item_layout = QHBoxLayout()
item_layout.addWidget(line_text)
item_layout.addWidget(line_push_button)
item_widget.setLayout(item_layout)
item.setSizeHint(item_widget.sizeHint())
self.ListWidget.addItem(item)
self.ListWidget.setItemWidget(item, item_widget)
...
def clicked(self):
sender = self.sender()
push_button = self.findChild(QPushButton, sender.objectName())
print(f'click: {push_button.objectName()}')
i'm trying to do a simple GUI for a python script that convert some text into a specific format but buttons doesn't show up in the window.
I first create the button class
class Button(QPushButton):
def __init__(self, btn_name=None):
super().__init__()
self.button = QPushButton(btn_name)
self.button.setCursor(
QCursor(QtCore.Qt.CursorShape.PointingHandCursor))
self.button.setStyleSheet(
"""*{border: 4px solid 'green';
border-radius: 45px;
font-size: 35px;
color: 'white';
padding: 25px 0;
margin: 100px, 200px}
*:hover{background: 'green'}
*:pressed{background: 'lightgreen'}"""
)
Then create the window class like this
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.window = QWidget()
self.window.resize(500, 500)
self.window.setWindowTitle("Pantuflis Software")
self.window.setFixedWidth(1000)
self.window.setStyleSheet("background: 'black';")
self.grid = QGridLayout()
self.window.setLayout(self.grid)
self.button = Button("Play")
self.grid.addWidget(self.button)
self.window.show()
Finally add the rest
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec())
But the button doesn't show up, only the main window does. I also tried the same but without creataing the button from my own class and works. Must be something wrong in the button class but i can't see what is.
If you are going to implement inherence then you have to apply the changes to the class. In your case it has a class that inherits from QPushButton but where you create the custom button which is not necessary, the same with the main window. My recommendation is that the OP should review his notes about inheritance.
import sys
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QCursor
from PyQt6.QtWidgets import QApplication, QGridLayout, QPushButton, QWidget
class Button(QPushButton):
def __init__(self, btn_name=""):
super().__init__(btn_name)
self.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
self.setStyleSheet(
"""*{border: 4px solid 'green';
border-radius: 45px;
font-size: 35px;
color: 'white';
padding: 25px 0;
margin: 100px, 200px}
*:hover{background: 'green'}
*:pressed{background: 'lightgreen'}"""
)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.resize(500, 500)
self.setWindowTitle("Pantuflis Software")
self.setFixedWidth(1000)
self.setStyleSheet("background: 'black';")
self.grid = QGridLayout(self)
self.button = Button("Play")
self.grid.addWidget(self.button)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
After studying various examples in this forum, I tried to change the color of a button when pressed. The button is normally blue, and when it is pressed I want it to turn red. The following code does display a blue button with white text, but it does not change to red when pressed. Please advise. I'm fairly new to learning python/pyqt5.
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton
class Push_button(QPushButton):
def __init__(self, parent=None):
super(Push_button, self).__init__(parent)
self.setStyleSheet("background-color: rgb(0,0,255); color: rgb(255,255,255); \
pressed {background-color : rgb(255,0,0); color: rgb(255,255,255);} ")
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.myButton = Push_button(self)
self.myButton.setText("myButton")
self.myButton.clicked.connect(self.myButtonClicked)
def myButtonClicked(self):
print("myButtonClicked")
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
You are not using selectors correctly.
Right now your stylesheet sets the blue background color universally, and the red color for classes named "pressed".
self.setStyleSheet('''
QPushButton {
background-color: rgb(0,0,255); color: rgb(255,255,255);
}
QPushButton:pressed {
background-color : rgb(255,0,0); color: rgb(255,255,255);
}
''')
Read more about selector types in the official documentation.
I'm trying to practise by making a Pokedex. I'm trying to dynamically create a list of buttons inside of an OVBoxLayout based on the response from an API call. The list of buttons is generated correctly however, none of the buttons work, code below:
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *
from app.pokeapi_client import PokeApiClient
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setup_styles()
self.pokemon_list_data = PokeApiClient().get_pokemon_list(limit=9)
self.setWindowTitle("Pokemon")
self.resize(1000, 800)
# create main layout
main_layout = QHBoxLayout()
# build list layout and populate with labels
self.pokemon_list_layout = QVBoxLayout()
self.populate_pokemon_list_layout()
# add list layout to main layout
main_layout.addLayout(self.pokemon_list_layout, 1)
self.setLayout(main_layout)
def populate_pokemon_list_layout(self):
for pokemon in self.pokemon_list_data['results']:
button = QPushButton(pokemon['name'])
button.clicked.connect(self.print_this)
self.pokemon_list_layout.addWidget(button)
def print_this(self):
print("hello world!")
def setup_styles(self):
self.setStyleSheet("""
QWidget {
background: red;
}
QPushButton {
color: white;
background: blue;
border: 1px solid white;
}
""")
The button.clicked.connect() doesn't appear to be assigning the function to each button, anyone know why this might be happening?
Here is a MRE with your code :
from PySide2 import QtWidgets
from PySide2 import QtCore
from PySide2 import QtGui
DATA = {'results':[{'name':'pikka'}, {'name': 'dracofeu'}, {'name': 'mewtwo'}]}
class MainWindow(QtWidgets.QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.pokemon_list_data = DATA #Emulation data
self.setWindowTitle("Pokemon")
# self.resize(1000, 800)
# create main layout
main_layout = QtWidgets.QHBoxLayout()
# build list layout and populate with labels
self.pokemon_list_layout = QtWidgets.QVBoxLayout()
self.populate_pokemon_list_layout()
# add list layout to main layout
main_layout.addLayout(self.pokemon_list_layout, 1)
self.setLayout(main_layout)
def populate_pokemon_list_layout(self):
for pokemon in self.pokemon_list_data['results']:
button = QtWidgets.QPushButton(pokemon['name'])
button.clicked.connect(self.print_this)
self.pokemon_list_layout.addWidget(button)
def print_this(self):
sender = self.sender()
print(sender.text())
app = QtWidgets.QApplication([])
test = MainWindow()
test.show()
app.exec_()
Here is the result :
As you can see I didn't change anything (except imports and the sender in the print_this method) but it works. I think you have a problem somewhere in your code.
I have a QDialog which contains a QGroupBox which in turn contains some push-buttons. I want to differentiate the background-color of the push-button which is clicked and all the remaining push-buttonx. How to achieve this?
Make sure the buttons are all children of the group-box, and then use findChildren to iterate over them. You could also use a QButtonGroup to help manage the buttons.
Here's a demo script to show how it could be done:
from PyQt5 import QtCore, QtWidgets
class Dialog(QtWidgets.QDialog):
def __init__(self):
super().__init__()
layout = QtWidgets.QVBoxLayout(self)
self.groupBox = QtWidgets.QGroupBox(self)
layout.addWidget(self.groupBox)
layout = QtWidgets.QVBoxLayout(self.groupBox)
for index in range(5):
button = QtWidgets.QPushButton('Button %d' % index, self.groupBox)
layout.addWidget(button)
self.buttonGroup = QtWidgets.QButtonGroup(self)
self.buttonGroup.buttonClicked.connect(self.handleButtonClicked)
self.updateButtonGroup()
def updateButtonGroup(self):
for button in self.groupBox.findChildren(QtWidgets.QPushButton):
if self.buttonGroup.id(button) < 0:
self.buttonGroup.addButton(button)
def handleButtonClicked(self, button):
for item in self.buttonGroup.buttons():
if button is item:
item.setStyleSheet('background-color: orange')
else:
item.setStyleSheet('')
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Dialog()
window.show()
sys.exit(app.exec_())
If reason to use class QtGui.QGroupBox is select button just like radio button, You can use Qt Style Sheet to set difference background color;
import sys
from PyQt4 import QtGui
class QCustomDialog (QtGui.QDialog):
def __init__(self, *args, **kwargs):
QtGui.QDialog.__init__(self, *args, **kwargs)
myQVBoxLayout = QtGui.QVBoxLayout()
for text in ['PyQt', 'Stack', 'Overflow']:
myQPushButton = QtGui.QPushButton(text)
myQPushButton.setCheckable(True)
myQPushButton.setAutoExclusive(True)
myQVBoxLayout.addWidget(myQPushButton)
myQVBoxLayout.addStretch(1)
myQGroupBox = QtGui.QGroupBox()
myQGroupBox.setStyleSheet('''
QPushButton {
border: 0px;
color: rgb(255, 255, 255);
background-color: rgb(0, 0, 0);
}
QPushButton:checked {
border: 0px;
color: rgb(255, 255, 255);
background-color: rgb(255, 0, 0);
}
''')
myQGroupBox.setLayout(myQVBoxLayout)
allQVBoxLayout = QtGui.QVBoxLayout()
allQVBoxLayout.addWidget(myQGroupBox)
self.setLayout(allQVBoxLayout)
myQApplication = QtGui.QApplication([])
myQCustomDialog = QCustomDialog()
myQCustomDialog.show()
sys.exit(myQApplication.exec_())