Coder Social home page Coder Social logo

pierreraybaut / formlayout Goto Github PK

View Code? Open in Web Editor NEW
27.0 10.0 14.0 249 KB

The most easy way to create Qt form dialogs and widgets with Python

Home Page: https://pypi.python.org/pypi/formlayout

License: MIT License

Python 94.46% Batchfile 1.14% Shell 4.39%

formlayout's People

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

formlayout's Issues

Drop support for PySide

PySide has been created by Nokia, Microsoft killed Nokia and so PySide and we only test PyQt in the Travis CI.

So, should we drop PySide support ?

Float field required in order for any of this code to work on matplotlib. If float field not input, form dialog does not open.

from matplotlib.backend_tools import ToolBase
from matplotlib.backends.qt_editor._formlayout import fedit
import matplotlib.pyplot as plt
import matplotlib
import pandas as pd
import os

class Save(ToolBase):

default_keymap = 'X'
description = 'Save dataframe to csv, xlsx, json, ubin, or hdf'
image = ''
df = pd.read_csv('C:\Python\PY3810_64v1\Lib\site-packages\\data\sample.csv')

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)

def trigger(self, *args):
    datalist = [('File Type', ['', '', 'xlsx', 'csv', 'json', 'ubin', 'hdf']),
                     ('', 0.0), # if this line is commented out, the code stops working with matplotlib plot --- this is where the issue lies
                    ('File Path', os.getcwd())]

    def apply_callback(data):
        (file, path) = data
        if file == 'csv':
                Save.df.to_csv('path')

    fedit(datalist, 'Excel', 'Save the current dataframe', parent=None, apply=apply_callback)

matplotlib.use('Qt5Agg', force=True)
plt.rcParams['toolbar'] = 'toolmanager'
fig, ax = plt.subplots()
fig.canvas.manager.toolmanager.add_tool('Save', Save)
fig.canvas.manager.toolbar.add_tool('Save', 1, -1)
plt.show()

Confusing error message when font does not exist

This was the biggest problem I had to solve when setting up the Travis testing.

In formlayout.py replace 'Arial' by 'InexistentFont' and then do python formlayout.py. The error you get is:

Traceback (most recent call last):
  File "formlayout.py", line 729, in <module>
    apply=apply_test))
  File "formlayout.py", line 691, in fedit
    dialog = FormDialog(data, title, comment, icon, parent, apply)
  File "formlayout.py", line 589, in __init__
    self.formwidget.setup()
  File "formlayout.py", line 409, in setup
    field.addItems(value)
TypeError: QComboBox.addItems(list-of-str): argument 1 has unexpected type 'list'

I believe that when the first item is 'font' we should raise an exception with a meaningful error message if we can not find the font. With the current code the tuple eventually reaches the QComboBox code and gives the confusing error message above.

"Required fields" feature would need some improvements

Required fields are not easy to find:

  • the label " *" suffix is not colored
  • the edit widget is not colored either when value is missing

I suggest one (or more) of the following:

  • label: changing the color of the asterisk (in red, typically) by modifying label (using html)
  • edit widget: change the color of the background when value is missing

How to change the background of the edit widget:
(this works with a QLineEdit or a QTextEdit but I doubt it has effect on a QComboBox, a FileLayout, or a RadioLayout)

    def required_valid(self):
        valid = True
        for field in self.required_fields:
            if not is_required_valid(field):
                valid = False
                field.setStyleSheet("background-color:rgb(255, 175, 90);")
            else:
                field.setStyleSheet("")
        self.update_buttons(valid)

Name change ?

@PierreRaybaut wrote formlayout as an utility for Spyder.

I think that a dead simple Python 2 and 3/QT 4 and 5 GUI lib is a benediction which could be useful for many little projects and successful of its own.

A new and sexiest name could be a plus.

getfile error

I'm using PySide, python 2.7, 32 bit on windows.
I get an error in getfile of FileLayout because the return value of QfileDialog.getOpenFileName is a tuple.
I've added the following test

       if name:
            if type(name) is tuple:
                name = name[0]
            self.lineedit.setText(name)

I also propose to replace the 'Browse' button in FileLayout, like this ๐Ÿ‘

    self.filebtn = QPushButton('...')
    self.filebtn.setFixedSize(20, 20)

About StyleSheet use

Qt StyleSheet is Sh*t, as you can see when we set the background color for 'required', we add the color but we loose all the other properties which result in ugly FileLayout button and ComboBox.

setStyleSheet(style) delete the old style, there isn't updateStyleSheet(style) method (no way to add just one property to a style).

The solution is to use setStyleSheet(styleSheet().append(style)), so for our custom widgets the setStyleSheet() method added is quite limited.

But the worst is that our first problem is not fixed, we can update a StyleSheet, but we can't update a Style with a StyleSheet. The hard-coded platform-mimic default Style is exploded by setStyleSheet().

I would like add more theme possibilities to formlayout, but this crap stops me.

Further explanation

Ensure compatibility with PyQt4 v4.4 (and earlier) by keeping old-style signals and slots

I have noticed that we progressively forgot to ensure compatibility with old-style signals and slots.

Unfortunately, that is not something we can test with travis because compatibility issues will cause silent fails (slots will not be triggered by emitted signals).

Here is what need to be fixed.
All occurences of the QObject method named connect need to be handled this way.
The following example:

self.widget.valueChanged.connect(layout.update)

should be replaced by:

if SIGNAL is None:
    self.widget.valueChanged.connect(layout.update)
else:
    self.connect(self.widget, SIGNAL("valueChanged(int)"), layout.update)

TypeError: 'PySide.QtGui.QSpinBox' object is not callable on Ubuntu 18.04

Trying to run the advanced.py example verbatim on my Ubuntu 18.04 system and getting this error message:

TypeError: 'PySide.QtGui.QSpinBox' object is not callable TypeError: 'PySide.QtGui.QSpinBox' object is not callable Traceback (most recent call last): File "gui.py", line 92, in <module> widget_color='#cf9')) File "/usr/local/lib/python2.7/dist-packages/formlayout.py", line 1272, in fedit widget_color) File "/usr/local/lib/python2.7/dist-packages/formlayout.py", line 1077, in __init__ self.formwidget.setup() File "/usr/local/lib/python2.7/dist-packages/formlayout.py", line 602, in setup field = SliderLayout(value, self) File "/usr/local/lib/python2.7/dist-packages/formlayout.py", line 301, in __init__ self.slider.setTickPosition(2) TypeError: 'PySide.QtGui.QSlider.setTickPosition' called with wrong argument types: PySide.QtGui.QSlider.setTickPosition(int) Supported signatures: PySide.QtGui.QSlider.setTickPosition(PySide.QtGui.QSlider.TickPosition)

simple.py works as expected.

Is this a pyside bug or an issue in formlayout?

Multiple Bool on same "row"

#1 Thank you for making this, literally made my month.
#2 I am trying to add a series of bool/checkbox's next to each other on same "row"/ horizontally, is this possible? If so, how?

Basically:
Mon () Tues () Wed () Thur () Fri () Sat() Sun()

Thank you

More documented examples

A lot of features have been added recently and should be documented to be maintained properly in the future.

The minimum should be to explain in a line comment the purpose of each line in the examples. But, now that formlayout (or should I write QuickForm) has a lot of features, without a decent documentation, maintaining the library could be difficult for people other than you: that is a real threat for the library sustainability.

License issue

formlayout is licensed under the MIT license, but use PyQt which is GPL licensed.

However, the GPL is the most famous copylefted license, and is strongly viral.

So formlayout can't stay under MIT and should be released under the GPL.

PySide has been re-coded from scratch by Nokia (under LGPL) only to address this licensing issue.

apply and type

apply and type are Python built-in so we should change the naming of this options.

formlayout program .exe build with pyinstaller, cx_freeze, or other.

@fgallaire Have you compiled a program with formlayout successfully with either of these programs? I spent the better part of yesterday and the day before, trying to get pyinstaller or cx_freeze to work. The error popping up, and I can't get around is: "import error: formlayout requires PyQT4, PyQt5 or PySide" Both pyinstaller and cx_freeze are pulling the PyQt5 libraries and files, but I get the same error for the compiled code using either pyinstaller or cx_freeze.

windows 7
Anaconda
Ipython 2.7.12 64bit

Thank you again,
R.

JSON serialization: datetime objects support

When trying to reintegrate all the formlayout.py into advanced.py (i.e. multiple string, datetime objects and font), I noticed the following traceback:

Traceback (most recent call last):
  File "C:\Python\formlayout\formlayout.py", line 780, in accept
    self.data = self.formwidget.get()
  File "C:\Python\formlayout\formlayout.py", line 646, in get
    dic[title] = json.loads(widget.get())
  File "C:\Python\formlayout\formlayout.py", line 547, in get
    return json.dumps(dic)
  File "C:\WinPython\install\WinPython-64bit-2.7.6.1\python-2.7.6.amd64\lib\json\__init__.py", line 243, in dumps
    return _default_encoder.encode(obj)
  File "C:\WinPython\install\WinPython-64bit-2.7.6.1\python-2.7.6.amd64\lib\json\encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\WinPython\install\WinPython-64bit-2.7.6.1\python-2.7.6.amd64\lib\json\encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "C:\WinPython\install\WinPython-64bit-2.7.6.1\python-2.7.6.amd64\lib\json\encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.date(2010, 10, 10) is not JSON serializable

So, I think we should either accept this JSON limitation (this is an expected error ; current implementation: 8f9622e) or we should add support for datetime objects (add a layer between formlayout and json) but I'm not sure it's worth it.

FormComboWidget and FormTabWidget catching conflict

if isinstance(data[0][0], (list, tuple)) it's a FormTabWidget
elif len(data[0]) == 3 it's a FormComboWidget (because (data, title, comment) tuple)
else it's a FormWidget (because (label, value) tuple)

It's OK when you want a FormComboWidget inside a FormTabWidget, but there's a catching conflict if you just want a FormComboWidget alone.

The datagroup example in advanced.py catch a FormTabwidget because the first test match, but it could be a FormComboWidget too.

successive calls to fedit()

Under Linux (Ubuntu 14.04), advanced.py fails.

The first call to fedit() is OK.

The second has an ugly GTK+ theme with multiple times this error message:

(python:15710): Gtk-CRITICAL **: IA__gtk_container_add: assertion 'GTK_IS_CONTAINER (container)' failed
(python:15710): Gtk-CRITICAL **: IA__gtk_widget_realize: assertion 'GTK_WIDGET_ANCHORED (widget) || GTK_IS_INVISIBLE (widget)' failed

The third fails completely:

Segmentation fault (core dumped)

Font selection

To choose a color we use QColorDialog.

To choose a font we use the custom FontLayout instead of QFontDialog, why this choice ?

Implement a Qt layout integration mode

Normally i woudl ask on a mailling list, but i did't find one. Is there a way to use formlayout to design normal widgets which than can be used in a pyqt application?

Dependency check fails with PyQt5

I have PyQt5 installed, but my os.environ['QT_API'] returns 'pyqt', erroneously classifying my PyQt version as PyQt4 and resulting in an ImportError when the following PyQt4 import inevitably fails. When I modified the check at the beginning of formlayout.py to attempt the PyQt5 imports instead, everything works perfectly, so this is a false positive failure.

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.