Giter VIP home page Giter VIP logo

pyqtconfig's People

Contributors

acreegan avatar brucelee569 avatar byt3m3 avatar jrast avatar mfitzp avatar pka avatar trappitsch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyqtconfig's Issues

Boolean values always retrieved as True from QSettings

A Boolean value is retrieved as unicode from QSettings' storage. The line https://github.com/mfitzp/pyqtconfig/blob/master/pyqtconfig/config.py#L983 compares the type to basestring, which then returns False so the type is not munged, which causes https://github.com/mfitzp/pyqtconfig/blob/master/pyqtconfig/config.py#L994 to become bool(u'value') and always return True. Changing the comparison to issubclass(vt, basestring) worked in my case.

$ python
Python 2.7.12 (default, Jul  1 2016, 15:12:24) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt5.QtCore import QT_VERSION_STR
>>> print QT_VERSION_STR
5.5.1
>>> from PyQt5.Qt import PYQT_VERSION_STR
>>> print PYQT_VERSION_STR
5.5.1
>>> from sip import SIP_VERSION_STR
>>> print SIP_VERSION_STR
4.17

$ lsb_release -a
LSB Version:    core-9.20160110ubuntu0.2-amd64:core-9.20160110ubuntu0.2-noarch:printing-9.20160110ubuntu0.2-amd64:printing-9.20160110ubuntu0.2-noarch:security-9.20160110ubuntu0.2-amd64:security-9.20160110ubuntu0.2-noarch
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.1 LTS
Release:        16.04
Codename:       xenial

Unable to use pyqtconfig module

I am unable to import or run the pyqtconfig module. Below is example of error I get. I have PySide2 and PyQt5 installed already.

PS C:\Users\MyUsername> python -m pyqtconfig.demo
Traceback (most recent call last):
  File "C:\Users\MyUsername\anaconda3\lib\runpy.py", line 183, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "C:\Users\MyUsername\anaconda3\lib\runpy.py", line 109, in _get_module_details
    __import__(pkg_name)
  File "C:\Users\MyUsername\anaconda3\lib\site-packages\pyqtconfig\__init__.py", line 1, in <module>
    from .config import *
  File "C:\Users\MyUsername\anaconda3\lib\site-packages\pyqtconfig\config.py", line 11, in <module>
    from .qt import (QComboBox, QCheckBox, QAction,
ImportError: cannot import name 'QComboBox' from 'pyqtconfig.qt' (C:\Users\MyUsername\anaconda3\lib\site-packages\pyqtconfig\qt.py)
PS C:\Users\MyUsername>

The settings_dialog_demo.py needs changes to work on Windows 10/11 and ZorinOS 16.3 Pro (Ubuntu) for PyQt6

In settings_dialog_demo.py line 48:

config_dialog = ConfigDialog(self.config, self, cols=2, f=Qt.WindowCloseButtonHint)

needs to be:

config_dialog = ConfigDialog(self.config, self, cols=2, flags=Qt.WindowType.WindowCloseButtonHint)

The PySide6 QDialog docs here

indicates that the "flags=" parameter name should be "f=". But with my PyQt6 installation it is "flags=".

I see in your config.py:ConfigDialog at line 1189 there is some code to try and handle the "f=" versus "flags=" issue for PyQt5 and PySide2, but not PyQt6 and PySide6, the relentless march of time changes things...

I thought the f= versus flags= was my real problem until I ran this on ZorinOS and I got more failure info than running it on Windows which informed me that:

    f=Qt.WindowCloseButtonHint,
       ^^^^^^^^^^^^^^^^^^^^^^^^
  AttributeError: type object 'Qt' has no attribute 'WindowCloseButtonHint'

It must be Qt.WindowType.WindowCloseButtonHint for PyQt6.

The PySide6 docs do not mention WindowType at all, there it is still: Qt.WindowCloseButtonHint.

So alot of confusion here. And to add insult to injury, not even passing the window manager hint flag on Windows and ZorinOs (Ubuntu) makes any difference. So I suspect this flag might make a difference on Mac -- I have not tried it there yet. My Macbook is in the closet somewhere.

Anyway, thanks for making pygqconfig -- it is really helpful -- and I thought you might be interested to having this information.

Can ConfigDialog use QTabWidget to put items in different tabs?

Hello,

I was looking through the source for pyqtconfig to get an idea of how to make hooks, and I noticed that there are hooks for QTabWidget, and was curious how QTabWidget is used.

Is it possible to configure the metadata when setting up a ConfigDialog class to put different config items on different tabs?

(also I'm not sure if this is the best place for questions)

Thanks,
Nick

Mapping of QCheckbox in Python3 and PyQt5 is always False

Hello,

first I want to say that I really like the idea of this project to allow handy mapping of Widgets and Settings.

Nonetheless I have an issue with the usage of QCheckBox with QSettingsManager. I' m using Python3.4 with PyQt5. If I uncheck my QCheckBox and restart my application it will start checked all the time.

I browsed a bit through the code and found that I have to supply a bool default value so that the _get() function of QSettingsManager can cast the value returned by QSettings().value() to bool.

I fixed this in my code:

self.settings = QSettingsManager()
self.settings.set_default('plot/autoscale', True)
self.autoscaleCheckbox = QCheckBox(self.tr("autoscale"))
self.settings.add_handler('plot/autoscale', self.autoscaleCheckbox)

Still it didn' t work. So I had a look in the _get() function of QSettingsMapper and found this condition on line 941:

    elif vt != dt and vt == unicode:

This condition is never True in Python3 as unicode has been declare as a function in line 144.

try:
    # Python2.7
    unicode
except:
    # Python3 recoding
    def unicode(s):
        if isinstance(s, bytes):
            return s.decode('utf-8')
        else:
            return s

So for Python3 all Strings are unicode so the condition should look like this:

    elif vt != dt and vt == str:

I' m aware that this solution wouldn' t work in Python2 but I have no other idea at the moment.

Greetings
Stefan

Feature Request: Save values of QSettingsManager manually

I often have the usecase of using a QDialog with OK and Cancel button to change certain settings. The changes made should only be stored if Ok was hit by the user. Otherwise they should be dismissed. Is there already a way to realise this feature? Otherwise it would be a great plus in usability.

PyQt6: Dialog Box issues / bugs

On PyQt6, the settings dialog cannot be opened and throws an error. This seems to be due to the fact, that in PyQt6, the standard dialog buttons moved, e.g., to QtWidgets.QMessageBox.StandardButton.Ok (from QtWidgets.QMessageBox.Ok in PyQt5).

Support for Inheritance

Currently the mapper is not working with inherited QWidget classes. Do you have any plans for fixing this?

Here is my Traceback:

Traceback (most recent call last):
  File "C:/Users/Lehmann/data/python34/ustempctrl/run_ustempctrl.pyw", line 14, in <module>
    w = CtrlTestGui()
  File "C:\Users\Lehmann\data\python34\ustempctrl\ustempctrl\mainwindow.py", line 49, in __init__
    self.plotsettings = PlotSettingsWidget(self)
  File "C:\Users\Lehmann\data\python34\ustempctrl\ustempctrl\plotsettings.py", line 38, in __init__
    self.settings.add_handler('plot/xmin', self.xminSpinBox)
  File "C:\Users\Lehmann\data\python34\pyqtconfig\pyqtconfig\config.py", line 800, in add_handler
    assert False, "No handler-functions available for this widget type (%s)" % type(handler).__name__
AssertionError: No handler-functions available for this widget type (CoordSpinBox)

Wrong module version in pip

It seems that wrong files are uploaded at version 0.9.1 which can be downloaded with 'pip install pyqtconfig'
There is difference in config.py file which is lacking of filename path feature for saving settings and some other features (shown on screenshot). Also module installed with pip install cannot run demo from github description.
At this moment to use module you have to manually clone repo and add it to code.
Screenshot_986

QtWebKit is deprecated

Dear maintainer

There's an issue with qt.py. You currently import PyQt5.QtWebKit, which is deprecated. pyqtconfig still works if you have pyqt5 installed via apt or dnf (which is QT 5.9.5 for me at this moment), but not if it's installed via pip3 (which is QT 5.11.1 for me at this moment). So there needs to be some kind of way to import either PyQt5.QtWebKit and PyQt5.QtWebKitWidgets or PyQt5.QtWebEngine and QtWebEngineWidgets, depending on PyQt5.QtCore.QT_VERSION_STR

I also have a question (which may or may not be a stupid question): why do you import everything from PyQt5.QtGui, PyQt5.QtCore, PyQt5.QtWebKit, PyQt5.QtNetwork, PyQt5.QtWidgets and PyQt5.QtWebKitWidgets? This way you have to have extra python packages installed which you don't necessarily need. Isn't there a way to do the imports as they are needed?

Support for QButtonGroup

Can you add support for QButtonGroups?

The code could looke something like this:

def _get_QButtonGroup(self):
    return [(nr, btn.isChecked()) for nr, btn in enumerate(self.buttons())]


def _set_QButtonGroup(self, v):
    for idx, state in v:
        self.buttons()[idx].setChecked(state)


def _event_QButtonGroup(self):
    return self.buttonClicked

Getting stuck with corrupt setting data for QButtonGroup in QSettingsManager

Just had the rare case of having corrupt data in one of my settings. In this specific case it was the mapping of QButtonGroup where the default value is something like [[0, True], [1, False], [2, False]]. But somehow I managed to save [None, [None]] as my settings value. Now everytime I try to add the handler for my ButtonGroup I get following error:

Traceback (most recent call last):
  File "C:/Users/Lehmann/data/python/python34/jsonwatchqt/run_jsonwatchqt.pyw", line 31, in <module>
    w = MainWindow()
  File "C:\Users\Lehmann\data\python\python34\jsonwatchqt\jsonwatchqt\mainwindow.py", line 87, in __init__
    self.plotsettings = PlotSettingsWidget(self.settings, self)
  File "C:\Users\Lehmann\data\python\python34\jsonwatchqt\jsonwatchqt\plotsettings.py", line 89, in __init__
    self.autoscaleButtonGroup)
  File "c:\users\lehmann\data\python\python34\pyqtconfig\pyqtconfig\config.py", line 824, in add_handler
    handler.setter(self._get(key))
  File "c:\users\lehmann\data\python\python34\pyqtconfig\pyqtconfig\config.py", line 568, in _set_QButtonGroup
    for idx, state in v:
TypeError: 'NoneType' object is not iterable

The only way I could help myself was to use another name for the setting. As the exception occurs in _set_QButtonGroup I thought about wrapping it in a try ... except right there.

def _set_QButtonGroup(self, v):
    """
        Set the states for all buttons in a group from a list of (index, checked) tuples
    """
    try:
        for idx, state in v:
            self.buttons()[idx].setChecked(state)
    except TypeError:
        pass

Allow passing arguments to QSettings()

It would be nice to have a option to pass arguments to the constructor of QSettings in the QSettingsManager.

I have made a quick fix for me to use a .ini file instead of the registry which looks something like this:

class IniSettingsManager(QSettingsManager):

    def __init__(self, path, defaults=None, *args, **kwargs):
        self.ini_path = path
        super(IniSettingsManager, self).__init__(defaults, *args, **kwargs)


    def reset(self):
        """
            Reset the config manager to it's initialised state.

            This initialises QSettings, unsets all defaults and removes all handlers, maps, and hooks.
        """
        self.settings = QSettings(self.ini_path, QSettings.IniFormat)
        self.handlers = {}
        self.handler_callbacks = {}
        self.defaults = {}
        self.maps = {}
        self.eventhooks = {}

index error with QSettingsManager

I’m getting

File "/Users/ajr/Projects/NET/zad/zad/views/settings.py", line 178, in setup
sc.add_handler("gen/ignored_nets", sd.ignoredListWidget)
File "/usr/local/py_env/zad/lib/python3.9/site-packages/pyqtconfig/config.py", line 877, in add_handler
handler.setter(self._get(key))
File "/usr/local/py_env/zad/lib/python3.9/site-packages/pyqtconfig/config.py", line 428, in _set_QListWidget
self.findItems(
IndexError: list index out of range

This happens if the list corresponding to the QListWidget is not empty.
I’m using pyqtconfig.QSettingsManager() and do not touch the QListWidget.
Instead I modify the settings by replacing the complete list with a modified (per GUI) one.

This is the code to access and set the list settings:


def getPrefs(self):
self.prefs = sc.get(self.listPrefName)
return

def addPref(self, value):
self.getPrefs()
self.prefs.append(value)
sc.set(self.listPrefName, self.prefs)
self.printSettings('End addPref')

def setPref(self, index, value):
self.prefs[index] = value
sc.set(self.listPrefName, self.prefs)

def delPref(self, value):
self.getPrefs()
self.prefs.remove(value)
sc.set(self.listPrefName, self.prefs)


self.prefs is the list of values.
self.listPrefName is something like ’gen/ip4_nets'
sc is the pyqtconfig.QSettingsManager instance.

What problem(s) does this package solve? Please describe in Introduction

Hi Martin,

In the introduction it would be nice to know up front what problem this package solves for PyQt GUI developers.

Why should someone invest the time to learn this and have another layer or object collection to maintain?

It is not obvious why it is easier to add this package to PyQt development projects. I am still learning PyQt so perhaps it is obvious to experienced PyQt development. What development or maintenance effort(s) does this package save?

Could someone please enhance the introduction to explain this?

Thank you.

no conversion with QSettingManager

Reagrding: "Note: On some platforms, versions of Qt, or Qt APIs QSettings will return strings for all values which can lead to complicated code and breakage. However, PyQtConfig is smart enough to use the type of the config parameter in defaults to auto-convert returned values.
However, you do not have to set defaults manually. As of v0.7 default values are auto-set when attaching widgets (handlers) to the config manager if they're not already set."

Using QSpinBox, it seems that when no default was defined, no conversion is done and a string is send to the setValue which raise an exception. My QSpinBox is created via qtdesigner.

from acquisition_gui import Ui_acquisitionDockWidget
self.ui = Ui_acquisitionDockWidget()
self.ui.setupUi(self)

self.settings = QSettingsManager()        self.settings.add_handler("acquisition/record_interval",self.ui.record_interval_spinBox)
      self.settings.add_handler("acquisition/number_records",self.ui.number_records_spinBox)

QComboBox should always use str when setting.

If you use a mapper dictionary and a value is missing, then if the actual values are non-string it will try and set this non-string on the QComboBox and error.

Missing values in the mapper should be handled transparently, and simply display the str equivalent of the value.

Implement __getitem__ and __setitem__ methods

It seems the current approach for managing config is with .get and .set methods.
I believe it would make sense to also implement __getitem__ and __setitem__ dunder methods in addition to this.

For example, the code example

config.set('number', 42)
config.get('number')

could also be written as

config["number"] = 42
config["number"]

Looking at the source, this should be a relatively small update to implement. If you think this would be acceptable, I am happy to add it myself and submit a PR.

Limits on auto-generated widgets for ConfigDialog

When using ConfigDialog to auto-generate a dialog for a settings dialog, there is no provision for values which are outside the default min/max range of the widget. For instance, the settings dict
default_settings = { "exposure_ms": 30, "X_Offset": 100, "Y_Offset": 100, "Width": 1000, "Height": 100, }
will auto-clip the four latter values to the default limit of QSpinBox, which is 99.

Is there any chance of automatically comparing the values to the limits, or equally providing ranges for values within the metadata?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.