View Single Post
Old 11-08-2015, 06:04 PM   #125
Groundhog
Coordinator
 
Join Date: Dec 2003
Location: Sydney, Australia
I put some work into cleaning up the code around styling the Qt forms, as this was some of the first coding I did and it lacks consistency, especially the first forms I put together. To be less polite, it works, but it's a real mess.

Qt Designer is one of the best reasons to use the Qt framework, but I really only use it to lay out my forms, and do all the actual styling from within Python. I chose to go this route (you could do it through Qt - you can set StyleSheets from within the Designer and see the results instantly), but if you want to be flexible and allow custom colour schemes you will be using the .setStyleSheet method for your widgets, and using the string formatted stylesheets, which are similar to .css in html, with variables.

As an example, a simple QPushButton widget's style sheet will look like:

Code:
standard_button = '''QPushButton {{ color: rgb{}; background-color: rgb{}; border-bottom-left-radius: {}px; border-bottom-right-radius: {}px; border-top-left-radius: {}px; border-top-right-radius: {}px; }} QPushButton:hover {{ background-color: rgb{}; }} QPushButton:disabled {{ background-color: rgb{}; color: rgb{}; }}'''

One of the downsides to Qt is that changing the original style is not enough to then go on and update all the widgets with it assigned - it's obviously just a stored string, so no signals are emitted to let all the widgets know to reapply it. I figured there would be a quick and easy way to do this, but after some google searches it seems not. To allow a user to change the colour of a push button, you will need to update the above string with the new rgb values, and then re-apply the stylesheet to all the widgets.

To handle this, I created a new class. I won't post the whole thing as it's huge, but this is a quick snippet of how it is structured for the settings screen:

Code:
class Style: def __init__(self, app): # The 'app' variable is my application itself, which gives the Style class access to directly modify all the widgets. # So when I create an instance of this class from within my application, I create it as self.style = Style(self). self.app = app # Class attributes - this will store all the stylesheets strings. self.attrs = {'css': {}} self.store_ss_strings() self.setup_shortcuts() self.init_all_widgets() def setup_shortcuts(self): # The quick command to retrieve the stylesheet and current variables stored in settings. self.mainwindow_panel = self.attrs['css']['mainwindow_panel'].format(self.retrieve_styling('mainwindow_panel')) def store_ss_strings(self): # Define all the stylesheets strings and store them in the self.attrs dictionary. self.attrs['css']['mainwindow_panel'] = mainwindow_panel = '''QLabel {{ color: rgb{}; background-color: rgba{}; border-bottom-left-radius: {}px; border-bottom-right-radius: {}px; border-top-left-radius: {}px; border-top-right-radius: {}px; }}''' def init_all_widgets(self): # This method is called upon creation of the class instance and applies all stylesheets to the different widgets, # via the individual method per Qt form. It uses the colours and other settings related to styling in the main # application's 'settings' class, so if changes are made to the colour scheme, this method is run again to re-style # everything. self.init_settings_form() def retrieve_styling(pointer): # Fetch the colours from settings class. if pointer == 'mainwindow_panel': r, g, b, a = self.app.settings.panel_background_color[0], self.app.settings.panel_background_color[1], \ self.app.settings.panel_background_color[2], self.app.settings.panel_transparency[0] # This dictionary supplies all the different settings needed by the stylesheet string. lookups = {'mainwindow_panel': (self.app.settings.panel_text_color, (r, g, b, a), self.app.settings.corner_radius, self.app.settings.corner_radius, self.app.settings.corner_radius, self.app.settings.corner_radius)} return lookups[pointer] def init_settings_form(self): # Apply the style sheets to all widgets. self.app.ui.settingsPanel.setStyleSheet(self.mainwindow_panel)
__________________
Politics, n. Strife of interests masquerading as a contest of principles.
--Ambrose Bierce
Groundhog is offline   Reply With Quote