pierreraybaut / formlayout Goto Github PK
View Code? Open in Web Editor NEWThe most easy way to create Qt form dialogs and widgets with Python
Home Page: https://pypi.python.org/pypi/formlayout
License: MIT License
The most easy way to create Qt form dialogs and widgets with Python
Home Page: https://pypi.python.org/pypi/formlayout
License: MIT License
The idea here is to implement a documentation analog to guidata
's:
It should includes the screenshots shown in README.md and setup.py long description (in the meantime, we point to the external link: http://static.freedownloadmanager.org/s/1182/1182265_2.jpg).
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 ?
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()
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 are not easy to find:
I suggest one (or more) of the following:
label
(using html)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)
@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.
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)
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.
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)
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?
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.
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
are Python built-in so we should change the naming of this options.
@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.
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.
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.
Following Issue #35, we will remove all the old-style signals and slots.
The following example:
if SIGNAL is None:
self.widget.valueChanged.connect(layout.update)
else:
self.connect(self.widget, SIGNAL("valueChanged(int)"), layout.update)
should be replaced by:
self.widget.valueChanged.connect(layout.update)
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)
To choose a color we use QColorDialog.
To choose a font we use the custom FontLayout instead of QFontDialog, why this choice ?
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?
The link from the Python wiki is broken (get's a 404 at https://code.google.com/archive/p/formlayout/ ) :
https://wiki.python.org/moin/GuiProgramming
I'd fix it, but I don't have a Python wiki account...
Cheers,
Tim.
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.