Merge pull request #726 from MikeTheWatchGuy/Dev-latest

openCV Demo port! Raw and Base64 image support, text justification, t…
This commit is contained in:
MikeTheWatchGuy 2018-11-16 11:23:15 -05:00 committed by GitHub
commit 010b7fded5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 264 additions and 76 deletions

46
HowDoI/readme.md Normal file
View File

@ -0,0 +1,46 @@
# PySimpleGUI-HowDoI
## Introduction
This package contains a GUI front-end to the AMAZING tool, HowDoI. You can ask this tool any programming question and it will tap into the enormous database of programming questions and answers, StackOverflow.
This program takes you question and returns CODE as a response.
The way it works is that it searches StackOverflow, gets the results and then finds the highest voted answer. From that answer it takes the code it finds and that is what is returned to you. It works shockingly well.
To learn more about HowDoI, visit their GitHub site:
https://github.com/gleitz/howdoi
![snag-0081](https://user-images.githubusercontent.com/13696193/46911287-3a151580-cf25-11e8-8328-f36fda446c4b.jpg)
Check out this example. This was not rehearsed. While typing this readme, an example was needed and a random question, that I've never asked before, was posed. Once again this program delivered a great answer.
You can copy and paste the solution right into your code if you wish.
## Installing
When you install PySimpleGUI-HowDoI, it will install the other components that it requires. To install, on windows, type this into a command prompt:
pip install pysimplegui-howdoi
## Running the GUI Program
Afer your Pip install completes you can run the program. Do run it, type this into your command prompt:
python -m pysimplegui-howdoi.pysimplegui-howdoi
Once running you simply type in your question and press enter or click the "SEND" button. If you want to ask a question again, you can use the arrow keys or your mouse wheel to access the history of questions you've previously asked.
Ask ANY question you want for ANY programming language. I recommend starting the question with the programming language.
## PySimpleGUI Project
This program was built as a sample application of the PySimpleGUI GUI Framework. It quickly became a tool I was unable to live without. I've been trying for some time to bring it to life for others to try.
## Windows Only?
This has only been tested using Windows. I have not gotten it to work under Linux. The linkage between the program and the howdoI package was messed up on Linux. If you're able to get a Linux version running, please let me know at info@PySimpleGUI.org

View File

@ -6,7 +6,20 @@ import textwrap
import pickle
import base64
import calendar
try:
from PySide2.QtWidgets import QApplication, QLabel, QWidget, QLineEdit, QComboBox, QFormLayout, QVBoxLayout, \
QHBoxLayout, QListWidget, QDial, QTableWidget
from PySide2.QtWidgets import QSlider, QCheckBox, QRadioButton, QSpinBox, QPushButton, QTextEdit, QMainWindow, QDialog, QAbstractItemView
from PySide2.QtWidgets import QSpacerItem, QFrame, QGroupBox, QTextBrowser, QPlainTextEdit, QButtonGroup, QFileDialog, QTableWidget, QTabWidget, QTabBar, QTreeWidget, QTreeWidgetItem, QLayout, QTreeWidgetItemIterator, QProgressBar
from PySide2.QtWidgets import QTableWidgetItem, QGraphicsView, QGraphicsScene, QGraphicsItemGroup, QMenu, QMenuBar, QAction, QSystemTrayIcon
from PySide2.QtGui import QPainter, QPixmap, QPen, QColor, QBrush, QPainterPath, QFont, QImage, QIcon
from PySide2.QtCore import Qt,QProcess, QEvent
import PySide2.QtGui as QtGui
import PySide2.QtCore as QtCore
import PySide2.QtWidgets as QtWidgets
using_pyqt5 = False
except:
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QLineEdit, QComboBox, QFormLayout, QVBoxLayout, \
QHBoxLayout, QListWidget, QDial, QTableWidget
from PyQt5.QtWidgets import QSlider, QCheckBox, QRadioButton, QSpinBox, QPushButton, QTextEdit, QMainWindow, QDialog, QAbstractItemView
@ -18,18 +31,6 @@ try:
import PyQt5.QtCore as QtCore
import PyQt5.QtWidgets as QtWidgets
using_pyqt5 = True
except:
from PySide2.QtWidgets import QApplication, QLabel, QWidget, QLineEdit, QComboBox, QFormLayout, QVBoxLayout, \
QHBoxLayout, QListWidget, QDial, QTableWidget
from PySide2.QtWidgets import QSlider, QCheckBox, QRadioButton, QSpinBox, QPushButton, QTextEdit, QMainWindow, QDialog, QAbstractItemView
from PySide2.QtWidgets import QSpacerItem, QFrame, QGroupBox, QTextBrowser, QPlainTextEdit, QButtonGroup, QFileDialog, QTableWidget, QTabWidget, QTabBar, QTreeWidget, QTreeWidgetItem, QLayout, QTreeWidgetItemIterator, QProgressBar
from PySide2.QtWidgets import QTableWidgetItem, QGraphicsView, QGraphicsScene, QGraphicsItemGroup, QMenu, QMenuBar, QAction
from PySide2.QtGui import QPainter, QPixmap, QPen, QColor, QBrush, QPainterPath, QFont, QImage, QIcon
from PySide2.QtCore import Qt,QProcess, QEvent
import PySide2.QtGui as QtGui
import PySide2.QtCore as QtCore
import PySide2.QtWidgets as QtWidgets
using_pyqt5 = False
"""
@ -91,7 +92,7 @@ DEFAULT_FONT = ("Helvetica", 10)
DEFAULT_TEXT_JUSTIFICATION = 'left'
DEFAULT_BORDER_WIDTH = 1
DEFAULT_AUTOCLOSE_TIME = 3 # time in seconds to show an autoclose form
DEFAULT_DEBUG_WINDOW_SIZE = (80, 20)
DEFAULT_DEBUG_WINDOW_SIZE = (800, 400)
DEFAULT_WINDOW_LOCATION = (None, None)
MAX_SCROLLED_TEXT_BOX_HEIGHT = 50
DEFAULT_TOOLTIP_TIME = 400
@ -297,10 +298,7 @@ class Element():
def __init__(self, type, size=(None, None), auto_size_text=None, font=None, background_color=None, text_color=None,
key=None, pad=None, tooltip=None):
if size[1] is not None and size[1] < 10: # change from character based size to pixels (roughly)
self.Size = size[0]*10, size[1]*25
else:
self.Size = size
self.Size = convert_tkinter_size_to_Qt(size)
self.Type = type
self.AutoSizeText = auto_size_text
self.Pad = DEFAULT_ELEMENT_PADDING if pad is None else pad
@ -936,8 +934,12 @@ class Multiline(Element, QWidget):
self.Autoscroll = autoscroll
self.Disabled = disabled
self.ChangeSubmits = change_submits
tsize = size # convert tkinter size to pixels
if size[0] is not None and size[0] < 100:
tsize = convert_tkinter_size_to_Qt(size)
super().__init__(ELEM_TYPE_INPUT_MULTILINE, size=size, auto_size_text=auto_size_text, background_color=bg,
super().__init__(ELEM_TYPE_INPUT_MULTILINE, size=tsize, auto_size_text=auto_size_text, background_color=bg,
text_color=fg, key=key, pad=pad, tooltip=tooltip, font=font or DEFAULT_FONT)
return
@ -1139,8 +1141,9 @@ class Output(Element):
bg = background_color if background_color else DEFAULT_INPUT_ELEMENTS_COLOR
fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR
tsize = convert_tkinter_size_to_Qt(size) if size[0] is not None and size[0] < 100 else size
super().__init__(ELEM_TYPE_OUTPUT, size=size, background_color=bg, text_color=fg, pad=pad, font=font,
super().__init__(ELEM_TYPE_OUTPUT, size=tsize, background_color=bg, text_color=fg, pad=pad, font=font,
tooltip=tooltip, key=key)
def reroute_stdout(self):
@ -1423,10 +1426,16 @@ class ProgressBar(Element):
self.Relief = relief if relief else DEFAULT_PROGRESS_BAR_RELIEF
self.BarExpired = False
self.StartValue = start_value
super().__init__(ELEM_TYPE_PROGRESS_BAR, size=size, auto_size_text=auto_size_text, key=key, pad=pad)
tsize = size
if size[0] is not None and size[0] < 100:
tsize = size[0]*10, size[1]*3
super().__init__(ELEM_TYPE_PROGRESS_BAR, size=tsize, auto_size_text=auto_size_text, key=key, pad=pad)
# returns False if update failed
def UpdateBar(self, current_count, max=None):
if max is not None:
self.QT_QProgressBar.setMaximum(max)
self.QT_QProgressBar.setValue(current_count)
self.ParentForm.QTApplication.processEvents() # refresh the window
@ -1440,7 +1449,7 @@ class ProgressBar(Element):
# Image #
# ---------------------------------------------------------------------- #
class Image(Element):
def __init__(self, filename=None, data=None, background_color=None, size=(None, None), pad=None, key=None,
def __init__(self, filename=None, data=None, data_base64=None, background_color=None, size=(None, None), pad=None, key=None,
tooltip=None):
'''
Image Element
@ -1454,15 +1463,16 @@ class Image(Element):
'''
self.Filename = filename
self.Data = data
self.DataBase64 = data_base64
self.tktext_label = None
self.BackgroundColor = background_color
if data is None and filename is None:
if data is None and filename is None and data_base64 is None:
print('* Warning... no image specified in Image Element! *')
super().__init__(ELEM_TYPE_IMAGE, size=size, background_color=background_color, pad=pad, key=key,
tooltip=tooltip)
return
def Update(self, filename=None, data=None, size=(None, None)):
def Update(self, filename=None, data=None, data_base64=None, size=(None, None)):
if filename is not None:
qlabel = self.QT_QLabel
qlabel.setText('')
@ -1473,11 +1483,17 @@ class Image(Element):
elif data is not None:
qlabel = self.QT_QLabel
qlabel.setText('')
ba = QtCore.QByteArray.fromBase64(data)
ba = QtCore.QByteArray.fromRawData(data)
pixmap = QtGui.QPixmap()
pixmap.loadFromData(ba)
qlabel.setPixmap(pixmap)
elif data_base64 is not None:
qlabel = self.QT_QLabel
qlabel.setText('')
ba = QtCore.QByteArray.fromBase64(data_base64)
pixmap = QtGui.QPixmap()
pixmap.loadFromData(ba)
qlabel.setPixmap(pixmap)
def __del__(self):
super().__del__()
@ -1991,7 +2007,8 @@ class Slider(Element):
temp_size = size
if temp_size == (None, None):
temp_size = (150, 30) if self.Orientation.startswith('h') else (30, 150)
elif size[0] is not None and size[0] < 100:
temp_size = size[0]*10, size[1]*3
super().__init__(ELEM_TYPE_INPUT_SLIDER, size=temp_size, font=font, background_color=background_color,
@ -2528,6 +2545,17 @@ class ErrorElement(Element):
super().__del__()
# ------------------------------------------------------------------------- #
# Tray CLASS #
# ------------------------------------------------------------------------- #
class Tray:
def __init__(self, title):
self.Title = title
def Read(self):
pass
# ------------------------------------------------------------------------- #
# Window CLASS #
# ------------------------------------------------------------------------- #
@ -2568,8 +2596,8 @@ class Window:
self.AutoSizeButtons = auto_size_buttons if auto_size_buttons is not None else DEFAULT_AUTOSIZE_BUTTONS
self.Title = title
self.Rows = [] # a list of ELEMENTS for this row
self.DefaultElementSize = default_element_size
self.DefaultButtonElementSize = default_button_element_size if default_button_element_size != (
self.DefaultElementSize = convert_tkinter_size_to_Qt(default_element_size)
self.DefaultButtonElementSize = convert_tkinter_size_to_Qt(default_button_element_size) if default_button_element_size != (
None, None) else DEFAULT_BUTTON_ELEMENT_SIZE
self.Location = location
self.ButtonColor = button_color if button_color else DEFAULT_BUTTON_COLOR
@ -2869,19 +2897,17 @@ class Window:
print('*** Error loading form to disk ***')
def GetScreenDimensions(self):
if self.TKrootDestroyed:
return None, None
# TODO
screen_width = screen_height = 0
return screen_width, screen_height
def Move(self, x, y):
try:
self.TKroot.geometry("+%s+%s" % (x, y))
except:
pass
# TODO
return
def Minimize(self):
self.TKroot.iconify()
# TODO
return
def StartMove(self, event):
try:
@ -2968,18 +2994,21 @@ class Window:
return
def Disable(self):
self.TKroot.grab_set_global()
# TODO
return
def Enable(self):
self.TKroot.grab_release()
# TODO
return
def Hide(self):
self._Hidden = True
self.TKroot.withdraw()
# TODO
return
def UnHide(self):
if self._Hidden:
self.TKroot.deiconify()
# TODO
self._Hidden = False
def Disappear(self):
@ -3122,6 +3151,20 @@ def element_callback_quit_mainloop(element):
element.ParentForm.QTApplication.exit() # kick the users out of the mainloop
# =========================================================================== #
# Stops the mainloop and sets the event information #
# =========================================================================== #
def convert_tkinter_size_to_Qt(size):
"""
Converts size in characters to size in pixels
:param size: size in characters, rows
:return: size in pixels, pixels
"""
qtsize = size
if size[1] is not None and size[1] < 10: # change from character based size to pixels (roughly)
qtsize = size[0]*10, size[1]*25
return qtsize
# ################################################################################
# ################################################################################
@ -3782,9 +3825,17 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win):
# ------------------------- TEXT element ------------------------- #
elif element_type == ELEM_TYPE_TEXT:
element.QT_Label = QLabel(element.DisplayText, toplevel_win.QTWindow)
if element.Justification[0] == 'c':
if element.Justification is not None:
justification = element.Justification
elif toplevel_win.TextJustification is not None:
justification = toplevel_win.TextJustification
else:
justification = DEFAULT_TEXT_JUSTIFICATION
if justification[0] == 'c':
element.QT_Label.setAlignment(Qt.AlignCenter)
elif element.Justification[0] == 'r':
elif justification[0] == 'r':
element.QT_Label.setAlignment(Qt.AlignRight)
if not auto_size_text:
if element_size[0] is not None:
@ -3804,8 +3855,8 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win):
if element.Tooltip:
element.QT_Label.setToolTip(element.Tooltip)
element.QT_Label.setMargin(full_element_pad[0])
element.QT_Label.setIndent(full_element_pad[1])
# element.QT_Label.setMargin(full_element_pad[0])
# element.QT_Label.setIndent(full_element_pad[1])
qt_row_layout.addWidget(element.QT_Label)
# ------------------------- BUTTON element ------------------------- #
elif element_type == ELEM_TYPE_BUTTON:
@ -4141,18 +4192,24 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win):
qt_row_layout.addWidget(element.QT_TextBrowser)
# ------------------------- IMAGE element ------------------------- #
elif element_type == ELEM_TYPE_IMAGE:
if element.Filename:
if element.Filename is not None:
qlabel = QLabel()
qlabel.setText('')
w = QtGui.QPixmap(element.Filename).width()
h = QtGui.QPixmap(element.Filename).height()
qlabel.setGeometry(QtCore.QRect(0, 0, w, h))
qlabel.setPixmap(QtGui.QPixmap(element.Filename))
elif element.Data:
elif element.Data is not None:
qlabel = QLabel()
qlabel.setText('')
ba = QtCore.QByteArray.fromBase64(element.Data)
ba = QtCore.QByteArray.fromRawData(element.Data)
pixmap = QtGui.QPixmap()
pixmap.loadFromData(ba)
qlabel.setPixmap(pixmap)
elif element.DataBase64:
qlabel = QLabel()
qlabel.setText('')
ba = QtCore.QByteArray.fromBase64(element.DataBase64)
pixmap = QtGui.QPixmap()
pixmap.loadFromData(ba)
qlabel.setPixmap(pixmap)
@ -4374,8 +4431,8 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win):
pass
# ............................DONE WITH ROW pack the row of widgets ..........................#
containing_frame.setSpacing(toplevel_win.ElementPadding[1])
qt_row_layout.setSpacing(toplevel_win.ElementPadding[0])
containing_frame.setSpacing(toplevel_win.ElementPadding[1])
containing_frame.addRow('', qt_row_layout)
# done with row, pack the row of widgets
@ -5070,10 +5127,10 @@ def SetOptions(icon=None, button_color=None, element_size=(None, None), button_e
DEFAULT_BUTTON_COLOR = button_color
if element_size != (None, None):
DEFAULT_ELEMENT_SIZE = element_size
DEFAULT_ELEMENT_SIZE = convert_tkinter_size_to_Qt(element_size)
if button_element_size != (None, None):
DEFAULT_BUTTON_ELEMENT_SIZE = button_element_size
DEFAULT_BUTTON_ELEMENT_SIZE = convert_tkinter_size_to_Qt(button_element_size)
if margins != (None, None):
DEFAULT_MARGINS = margins
@ -5512,8 +5569,8 @@ def ObjToString(obj, extra=' '):
# ----------------------------------- The mighty Popup! ------------------------------------------------------------ #
def Popup(*args, button_color=None, background_color=None, text_color=None, button_type=POPUP_BUTTONS_OK,
auto_close=False, auto_close_duration=None, non_blocking=False, icon=DEFAULT_WINDOW_ICON, line_width=None,
font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None)):
auto_close=False, auto_close_duration=None, custom_text=(None, None), non_blocking=False, icon=DEFAULT_WINDOW_ICON, line_width=None,
font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), use_system_tray=False):
"""
Popup - Display a popup box with as many parms as you wish to include
:param args:
@ -5535,6 +5592,9 @@ def Popup(*args, button_color=None, background_color=None, text_color=None, butt
"""
global _my_windows
# if use_system_tray:
# QSystemTrayIcon.
if not args:
args_to_print = ['']
else:
@ -5548,6 +5608,7 @@ def Popup(*args, button_color=None, background_color=None, text_color=None, butt
auto_close=auto_close, auto_close_duration=auto_close_duration, icon=icon, font=font,
no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location)
max_line_total, total_lines = 0, 0
layout = []
for message in args_to_print:
# fancy code to check if string and convert if not is not need. Just always convert to string :-)
# if not isinstance(message, str): message = str(message)
@ -5562,34 +5623,43 @@ def Popup(*args, button_color=None, background_color=None, text_color=None, butt
max_line_total = max(max_line_total, width_used)
# height = _GetNumLinesNeeded(message, width_used)
height = message_wrapped_lines
window.AddRow(
Text(message_wrapped, auto_size_text=True, text_color=text_color, background_color=background_color))
layout.append([Text(message_wrapped, auto_size_text=True, text_color=text_color, background_color=background_color)])
total_lines += height
if total_lines < 3:
[window.AddRow(Text('')) for i in range(2)]
layout.append([Text('')])
layout.append([Text('')])
if non_blocking:
PopupButton = DummyButton # important to use or else button will close other windows too!
else:
PopupButton = CloseButton
# show either an OK or Yes/No depending on paramater
if button_type is POPUP_BUTTONS_YES_NO:
window.AddRow(PopupButton('Yes', button_color=button_color, focus=True, bind_return_key=True, pad=((20, 5), 3),
size=(60, 20)), PopupButton('No', button_color=button_color, size=(60, 20)))
# show either an OK or Yes/No depending on paramater
if custom_text != (None, None):
if type(custom_text) is not tuple:
window.AddRow(PopupButton(custom_text, button_color=button_color, focus=True, bind_return_key=True))
elif custom_text[1] is None:
window.AddRow(PopupButton(custom_text[0], button_color=button_color, focus=True, bind_return_key=True))
else:
window.AddRow(PopupButton(custom_text[0], button_color=button_color, focus=True, bind_return_key=True),
PopupButton(custom_text[1], button_color=button_color),Stretch())
elif button_type is POPUP_BUTTONS_YES_NO:
layout.append([PopupButton('Yes', button_color=button_color, focus=True, bind_return_key=True, pad=((20, 5), 3),
size=(60, 20)), PopupButton('No', button_color=button_color, size=(60, 20))])
elif button_type is POPUP_BUTTONS_CANCELLED:
window.AddRow(
PopupButton('Cancelled', button_color=button_color, focus=True, bind_return_key=True, pad=((20, 0), 3)))
layout.append([PopupButton('Cancelled', button_color=button_color, focus=True, bind_return_key=True, pad=((20, 0), 3)), Stretch()])
elif button_type is POPUP_BUTTONS_ERROR:
window.AddRow(PopupButton('Error', size=(60, 20), button_color=button_color, focus=True, bind_return_key=True,
pad=((20, 0), 3)))
layout.append([PopupButton('Error', size=(60, 20), button_color=button_color, focus=True, bind_return_key=True,
pad=((20, 0), 3)), Stretch()])
elif button_type is POPUP_BUTTONS_OK_CANCEL:
window.AddRow(PopupButton('OK', size=(60, 20), button_color=button_color, focus=True, bind_return_key=True),
PopupButton('Cancel', size=(60, 20), button_color=button_color))
layout.append([PopupButton('OK', size=(60, 20), button_color=button_color, focus=True, bind_return_key=True),
PopupButton('Cancel', size=(60, 20), button_color=button_color), Stretch()])
elif button_type is POPUP_BUTTONS_NO_BUTTONS:
pass
else:
window.AddRow(PopupButton('OK', size=(60, 20), button_color=button_color, focus=True, bind_return_key=True))
layout.append([PopupButton('OK', size=(60, 20), button_color=button_color, focus=True, bind_return_key=True), Stretch()])
window.Layout(layout)
if non_blocking:
button, values = window.Read(timeout=0)
_my_windows.active_popups[window] = title
@ -5704,7 +5774,7 @@ def PopupQuick(*args, button_type=POPUP_BUTTONS_OK, button_color=None, backgroun
# --------------------------- PopupQuick - a NonBlocking, Self-closing Popup with no titlebar and no buttons ---------------------------
def PopupQuickMessage(*args, button_type=POPUP_BUTTONS_NO_BUTTONS, button_color=None, background_color=None,
text_color=None,
auto_close=True, auto_close_duration=2, non_blocking=True, icon=DEFAULT_WINDOW_ICON,
auto_close=True, auto_close_duration=4, non_blocking=True, icon=DEFAULT_WINDOW_ICON,
line_width=None,
font=None, no_titlebar=True, grab_anywhere=False, keep_on_top=False, location=(None, None)):
"""
@ -5769,7 +5839,7 @@ PopupAnnoying = PopupNoTitlebar
# --------------------------- PopupAutoClose ---------------------------
def PopupAutoClose(*args, button_type=POPUP_BUTTONS_OK, button_color=None, background_color=None, text_color=None,
auto_close=True, auto_close_duration=None, non_blocking=False, icon=DEFAULT_WINDOW_ICON,
auto_close=True, auto_close_duration=DEFAULT_AUTOCLOSE_TIME, non_blocking=False, icon=DEFAULT_WINDOW_ICON,
line_width=None, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False,
location=(None, None)):
"""

View File

@ -0,0 +1,59 @@
#!/usr/bin/env python
import sys
if sys.version_info[0] >= 3:
import PySimpleGUIQt as sg
else:
import PySimpleGUI27 as sg
import cv2
import numpy as np
from sys import exit as exit
"""
Demo program that displays a webcam using OpenCV
"""
def main():
sg.ChangeLookAndFeel('LightGreen')
# define the window layout
layout = [[sg.Text('OpenCV Demo', size=(40, 1), justification='center', font='Helvetica 20')],
[sg.Image(filename='', key='image')],
[sg.Button('Record', size=(10, 1), font='Helvetica 14'),
sg.Button('Stop', size=(10, 1), font='Any 14'),
sg.Button('Exit', size=(10, 1), font='Helvetica 14'),
sg.Button('About', size=(10,1), font='Any 14')]]
# create the window and show it without the plot
window = sg.Window('Demo Application - OpenCV Integration',
location=(800,400))
window.Layout(layout)
# ---===--- Event LOOP Read and display frames, operate the GUI --- #
cap = cv2.VideoCapture(0)
recording = False
while True:
event, values = window.Read(timeout=0, timeout_key='timeout')
if event == 'Exit' or event is None:
sys.exit(0)
pass
elif event == 'Record':
recording = True
elif event == 'Stop':
recording = False
# img = np.full((480, 640),255)
# imgbytes=cv2.imencode('.png', img)[1].tobytes() #this is faster, shorter and needs less includes
# window.FindElement('image').Update(data=imgbytes)
elif event == 'About':
sg.PopupNoWait('Made with PySimpleGUI',
'www.PySimpleGUI.org',
'Check out how the video keeps playing behind this window.',
'I finally figured out how to display frames from a webcam.',
'ENJOY! Go make something really cool with this... please!',
keep_on_top=True)
if recording:
ret, frame = cap.read()
imgbytes=cv2.imencode('.png', frame)[1].tobytes() #ditto
window.FindElement('image').Update(data=imgbytes)
main()
exit()

View File

@ -36,34 +36,47 @@ Welcome to the Alpha Release of PySimpleGUI for Qt!
You can use the exact same code that you are running on the older, tkinter, version of PySimpleGUI.
PySimpleGUIQt uses **PySide2** for access to Qt.
PySimpleGUIQt uses **PySide2** OR **PyQt5** for access to Qt.
### Differences between PySimpleGUI and PySimpleGUIQt
## Porting your PySimpleGUI code to PySimpleGUIQt
To "port" your code from the tkinter implementation. Follow these steps:
1. Change `import PySimpleGUI` to `PySimpleGUIQt`
That's it! OK, maybe I should have said step instead of steps.
## Differences between PySimpleGUI and PySimpleGUIQt
#### Sizes
IMPORTANT NOTE if you are porting from tkinter to Qt - You will need to make one important change to your code.... **You must change your size parameters to be in PIXELS instead of CHARACTERS**.
While you can use "Character-based" sizes like you did in tkinter, it's best to use pixel based sizes as that is what Qt uses. PySimpleGUIQt does some very rough / basic conversions from the character sizes to pixel sizes. It's enough that your elements will at least be visible. But the conversion is likely to not be ideal.
#### Fonts
Fonts should be in the format (font family, size). The original PySimpleGUI also allowed a font string 'Family Size' but that option is not available (yet) in the Qt version. I'll add it though so the code ports straight over.
Fonts should be in the format (font family, size). You can use the older string based too, but it will not work with setting like bold and italics. PySimpleGUIQt converts from the string 'Courier 20' to the tuple ('Courier', 20) for you.
### Installing PySimpleGUIQt for Python 3
pip install --upgrade PySimpleGUIQt
On some systems you need to run pip3.
On Linux systems you need to run pip3.
pip3 install --upgrade PySimpleGUIQt
### Installing PySide2 for Python 3
### Installing PySide2 or PyQt5 for Python 3
It is recommended that you use PySide2, however, if that cannot be found, then PyQt5 will be attempted. To install either of these:
```pip install PySide2```
or
```pip install PyQt5```
## Testing your installation
@ -85,7 +98,7 @@ Here is the window you should see:
## Prerequisites
Python 3
PySide2
PySide2 or PyQt5