I've got a pretty large PyQt5 application that I'm finally polishing with some colors. I've created a QPalette()
and pass that to the app at launch. For the most part, it works (yay!). But not all of the child widgets are picking up the QPalette settings, and so I added a StyleSheet, but that again isn't working consistently. The only way I've been able to impact a widget color is by directly adding it when the widget is created, which is fine in something small.
The Main window:
class MyBigApplication(QMainWindow, QWidget):
def __init__(self):
super(MyBigApplication, self).__init__()
# ... load the various pieces, which include prompting user login and making some background connections.
# Build the GUI
def init_ui(self):
self.statusBar().showMessage('Welcome to MyBigApplication!')
self.grid_layout = QGridLayout()
# Initialize tab screen
self.tabs = QTabWidget()
self.tabs.setTabShape(QTabWidget.Triangular)
self.foo = fooTab(self, self.tabs)
self.bar = barTab(self, self.tabs)
self.baz = bazTab(self, self.tabs)
self.grid_layout.addWidget(self.tabs,0,1,4,1)
main_widget = QWidget()
main_widget.setLayout(self.grid_layout)
self.setCentralWidget(main_widget)
# Additional setup of menus and such
if __name__.endswith('__main__'):
app = QCoreApplication.instance()
while app is not None:
app.close()
app = QApplication(sys.argv)
app.setStyle('Fusion')
dark_palette = QPalette()
# Define some colors to get started
light_grey = QColor(243,243,243)
medium_grey = QColor(211,216,219)
dark_grey = QColor(52,59,64)
dark_palette.setColor(QPalette.Window, QColor(dark_grey))
dark_palette.setColor(QPalette.AlternateBase, QColor(medium_grey))
dark_palette.setColor(QPalette.Button, QColor(dark_grey))
dark_palette.setColor(QPalette.Base, QColor(25, 25, 25)) # almost black
dark_palette.setColor(QPalette.Link, QColor(green))
dark_palette.setColor(QPalette.Highlight, QColor(half_green))
dark_palette.setColor(QPalette.WindowText, QColor(light_grey))
dark_palette.setColor(QPalette.ToolTipBase, QColor(light_grey))
dark_palette.setColor(QPalette.ToolTipText, QColor(light_grey))
dark_palette.setColor(QPalette.Text, QColor(light_grey))
dark_palette.setColor(QPalette.ButtonText, QColor(light_grey))
dark_palette.setColor(QPalette.BrightText, Qt.red)
dark_palette.setColor(QPalette.HighlightedText, Qt.black)
app.setPalette(dark_palette)
app.setFont(QFont('Franklin Gothic Book', 9))
app.setStyleSheet("""
QMainWindow {
}
QToolTip {
color: #f3f3f3;
background-color: #2a82da;
border: 1px solid white;
}
QTableView { # This works
border: 1px solid #218a21
}
QPushButton { # And this works
padding: 10px 15px 10px 15px,
}
QPushButton:hover { # But this does not
background-color: red,
}
QTableView::item:alternate { # And this also does not
background-color: #d3d8db,
}
""")
execute = MyBigApplication()
sys.exit(app.exec_())
The fooTab includes tables of data:
class fooTab(QWidget):
def __init__(self, parent, tabs):
super(fooTab,self).__init__()
self.root = parent
self.tabs = tabs
def init_foo_one(self):
self.foo_tab = QWidget()
self.tabs.addTab(self.foo_tab, 'FOO')
tab_layout = QVBoxLayout()
foo_id_box = QGroupBox('FOO DATA')
clear_button = QPushButton('Clear Foo Data Table')
clear_button.clicked.connect(self.clear_foo_table)
# Set up the Table Model/View/Proxy
self.foo_id_table = QTableView()
self.foo_data_model = fooTableModel() # This is a QAbstractTableModel class
self.foo_data_model.setDataDict(data)
self.foo_id_table_columns = ['1','2','3','4']
self.foo_resizable_cols = [0,1,2,3,4]
self.foo_data_model.setDataHeader(self.foo_id_table_columns)
self.foo_table_proxy.setSourceModel(self.foo_data_model)
self.foo_id_table.setModel(self.foo_table_proxy)
self.foo_id_table.setSelectionBehavior(QAbstractItemView.SelectRows)
self.foo_id_table.setSortingEnabled(True)
self.foo_id_table.setWordWrap(False)
self.foo_id_table.setAlternatingRowColors(True)
# Create a layout for that box using a grid
foo_id_box_layout = QGridLayout()
# Add the widgets into the layout
foo_id_box_layout.addWidget(self.foo_id_table,0,0,1,5)
foo_id_box_layout.addWidget(clear_button,1,2,1,1)
# Setup the layout to be displayed in the box
foo_id_box.setLayout(foo_id_box_layout)
tab_layout.addWidget(foo_id_box)
self.foo_tab.setLayout(tab_layout)
The bazTab:
class BazTab(QWidget):
def __init__(self, parent, tabs):
super(BazTab,self).__init__()
self.root = parent
self.tabs = tabs
self.h1_font = QFont()
self.h1_font.setBold(True)
self.h1_font.setPointSize(16)
self.h2_font = QFont()
self.h2_font.setBold(False)
self.h2_font.setPointSize(12)
self.h3_font = QFont()
self.h3_font.setBold(True)
self.init_ui()
def init_ui(self):
self.component_tab = QScrollArea()
self.tabs.addTab(self.baz_tab, 'Baz')
self.tab_layout = QHBoxLayout()
self.component_tab.setLayout(self.tab_layout)
component_button_box = QGroupBox('Various Buttons')
component_button_layout = QVBoxLayout()
component_button_layout.setAlignment(Qt.AlignTop)
component_button_box.setLayout(component_button_layout)
self.tab_layout.addWidget(component_button_box)
first_button = QPushButton('Request #1')
first_button.clicked.connect(self.request_one)
component_button_layout.addWidget(first_button)
second_button = QPushButton('Request #2')
second_button.clicked.connect(self.request_two)
component_button_layout.addWidget(second_button)
# Several more buttons created in here
# None of these buttons look like the buttons in the info dialog (which have a color from the QPalette)
I can manually edit the QTableView
to show alternating colors, only if I add it to each instance.
I cannot get some of the QPushButtons to change, even when I add each instance's styleSheet.
Using the QPalette has saved a ton, by not having to modify widget by widget. For the extra details, I'm fine to use the app.setStyleSheet
except that it doesn't always work.
Is it me, or is this just the way it is?