After freezing my Python programs using cx_freeze, I tried to run exe file created but its not running.
PhoneBook.py
import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtUiTools import *
class PhoneBook:
i=0;
def __init__(self):
loader = QUiLoader();
file = QFile("PhoneBook.ui");
file.open(QFile.ReadOnly);
self.ui = loader.load(file);
file.close();
self.ui.setWindowIcon(QIcon('web.png'));
self.ui.pushButton.clicked.connect(self.add);
self.ui.pushButton_2.clicked.connect(self.load);
def __del__ ( self ):
self.ui = None;
def add(self):
loader1 = QUiLoader();
file1 = QFile("Add.ui");
file1.open(QFile.ReadOnly);
self.ui2 = loader1.load(file1);
file1.close();
self.ui2.show();
self.ui2.pushButton.clicked.connect(self.get);
def show(self):
self.ui.show();
def clear1(self):
self.ui.lineEdit.clear();
def get(self):
name1 = self.ui2.lineEdit.text();
name2 = self.ui2.lineEdit_2.text();
f = open('data','a' );
f.write(name1);
f.write('#');
f.write(name2);
f.write('\n');
f.close();
self.load();
self.ui2.close();
def load(self):
f = open('data', 'r');
for i in range(0, 10):
string = f.readline();
l=len(string);
print(string);
print(l);
for c in range(0, l-1):
if string[c]=="#":
break;
print(c);
name1=string[0:c];
name2=string[c+1:l-1];
self.ui.tableWidget.setItem(i, 0, QTableWidgetItem(name1));
self.ui.tableWidget.setItem(i, 1, QTableWidgetItem(name2));
i =i+1;
def sort(self):
f=open('data', 'r');
f.readlines().sort();
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setApplicationName('PhoneBook Application')
w = PhoneBook();
w.show();
QObject.connect(app, SIGNAL('lastWindowClosed()'), app,SLOT('quit()'))
sys.exit(app.exec_())
setup.py
import sys
from cx_Freeze import setup,Executable
includefiles = ['Add.ui', 'PhoneBook.ui', 'data', 'web.png']
includes = ["re"]
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup(name="PhoneBook", version="3.0",description="Test",options = {'build_exe': {'include_files':includefiles, 'includes' : includes}
Is it because I am using QUILoader ? However on executing the Python code directly its showing correct results. Please help me.
From the docs its seems that you must include atexit
cxfreeze yourapp.py --target-dir dist --base-name Win32GUI --include-modules atexit,PySide.QtNetwork --icon yourapptaskgroup.ico
The site specifically mentions that if you don't include atextit , the installer is not going to work
“atexit” must be included in —include-modules, otherwise the generated exe will fail.
Link to the knowledge base article
Another cause of error was that cx-freeze was using some dlls from PyQt.
And the dlls are not same in pyside and pyqt, so if you have pyqt insalled i would suggest adding PyQt4 to the excludes
excludes=['PyQt4', 'tcl', 'tk', 'ttk', 'tkinter', 'Tkconstants', 'Tkinter', "collections.sys", "collections._weakref"]
Related
i have a written piece of code of around 100 lines which is printing some output of around 20 lines. How can I print this output in GUI ??
I just wrote this implementation for a project of mine, its in Python 2.7 but it should be easy to adapt it to Python 3.6
#!/usr/lib/python2.7/
# -*- coding: utf-8 -*-
from Tkinter import *
import ttk, collections
class GUI():
def __init__(self) :
self.window = Tk()
def draw(self) :
self.root = Frame(self.window,padx=15,pady=15,width=800,height=200)
self.root.grid(column=0,row=0)
self.drawConsole()
self.window.mainloop()
def drawConsole(self) :
self.consoleFrame = Frame(self.root, padx=15)
self.consoleFrame.grid(column=0,row=4,sticky="EW",pady=10)
self.logTest = Text(self.consoleFrame, height=15, state='disabled', wrap='word',background='black',foreground='yellow')
self.logTest.grid(column=0,row=0,sticky="EW")
self.scrollbar = Scrollbar(self.consoleFrame, orient=VERTICAL,command=self.logTest.yview)
self.scrollbar.grid(column=1,row=0,sticky=(N,S))
self.logTest['yscrollcommand'] = self.scrollbar.set
def writeToLog(self, msg):
numlines = self.logTest.index('end - 1 line').split('.')[0]
self.logTest['state'] = 'normal'
if numlines==24:
self.logTest.delete(1.0, 2.0)
if self.logTest.index('end-1c')!='1.0':
self.logTest.insert('end', '\n')
self.logTest.insert('end', msg)
self.logTest.see(END)
self.logTest['state'] = 'disabled'
if __name__ == "__main__":
gui = GUI()
gui.draw()
gui.writeToLog("Hello World")
I am a Python 3.x guy, but when it comes to tkinter, you can set labels with variables instead of using print(). So to get it on the GUI, you want to set labels with variables. This would look something like this:
from tkinter import *
window = Tk()
variable = StringVar()
variable.set(data_to_console) #You can use a variable with a string here or any string
label = Label(window, textvariable=variable)
label.grid(row=x, column=y)
So you take the strings that would be output into the console and use .set() to put it into a String Variable that tkinter can use. The Labels will allow for the data that would be printed to be in the GUI. Hope this helps!
I'm working on a GStreamer-based program using Python and the GObject introspection bindings. I'm trying to build this pipeline:
videomixer name=mix ! autovideosink \
uridecodebin uri=v4l2:///dev/video0 ! mix.
The pipeline works perfectly using gst-launch-1.0, but my Python program gives the errors:
(minimal.py:12168): GStreamer-CRITICAL **: gst_element_link_pads_full: assertion 'GST_IS_ELEMENT (src)' failed
on_error(): (GError('Internal data flow error.',), 'gstbasesrc.c(2865): gst_base_src_loop (): /GstPipeline:pipeline0/GstURIDecodeBin:uridecodebin0/GstV4l2Src:source:\nstreaming task paused, reason not-linked (-1)')
My code:
#!/usr/bin/python3
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst, Gtk, GdkX11, GstVideo
GObject.threads_init()
Gst.init(None)
class Source:
def __init__(self, uri, pipeline, mixer):
self.uri = uri
self.pipeline = pipeline
self.mixer = mixer
self.src = Gst.ElementFactory.make('uridecodebin', None)
self.pipeline.add(self.src)
self.src.set_property('uri', uri)
self.src.connect('pad-added', self.on_pad_added, self.src, self.mixer)
def on_pad_added(self, element, pad, src, dest):
name = pad.query_caps(None).to_string()
print('on_pad_added:', name)
if name.startswith('video/'):
src.link(dest)
class Main:
def __init__(self):
self.window = Gtk.Window()
self.window.connect('destroy', self.quit)
self.window.set_default_size(1280, 720)
self.drawingarea = Gtk.DrawingArea()
self.window.add(self.drawingarea)
self.pipeline = Gst.Pipeline()
self.bus = self.pipeline.get_bus()
self.bus.add_signal_watch()
self.bus.connect('message::error', self.on_error)
self.bus.enable_sync_message_emission()
self.bus.connect('sync-message::element', self.on_sync_message)
self.mixer = Gst.ElementFactory.make('videomixer', None)
self.sink = Gst.ElementFactory.make('autovideosink', None)
self.pipeline.add(self.mixer)
self.pipeline.add(self.sink)
self.mixer.link(self.sink)
video = Source('v4l2:///dev/video0', self.pipeline, self.mixer)
def run(self):
self.window.show_all()
# You need to get the XID after window.show_all(). You shouldn't get it
# in the on_sync_message() handler because threading issues will cause
# segfaults there.
self.xid = self.drawingarea.get_property('window').get_xid()
self.pipeline.set_state(Gst.State.PLAYING)
Gtk.main()
def quit(self, window):
self.pipeline.set_state(Gst.State.NULL)
Gtk.main_quit()
def on_sync_message(self, bus, msg):
if msg.get_structure().get_name() == 'prepare-window-handle': msg.src.set_window_handle(self.xid)
def on_error(self, bus, msg):
print('on_error():', msg.parse_error())
main = Main()
main.run()
I figured out the problem, I was linking the dynamically-created pad incorrectly:
src.link(dest)
Should have been:
pad.link(dest.get_compatible_pad(pad, None))
If the element is not added with the pipeline, then this error will occur. Ensure that the problematic element is added with the pipeline.
I am essentially repeating a question that was asked (but not answered) in the comments of PyQt: Getting file name for file dropped in app .
What I'd like to be able to do, a la that post, is convert an output from a file drop event in pyqt that currently looks like this:
/.file/id=6571367.661326 into an actual file path (i.e. /.Documents/etc./etc./myProject/fileNeeded.extension)
so that I can make use of the file that made the attempted QDropEvent. how to do this. Any thoughts?
EDIT:
As mentioned below in the comments, this appears to be a platform specific problem. I am running Mac OS X El Capitan (10.11.2)
I figured out the solution after translating Obj-C code found in https://bugreports.qt.io/browse/QTBUG-40449. Note that this solution is only necessary for Macs running OS X Yosemite or later AND not running PyQt5 (i.e. running v.4.8 in my case).
import objc
import CoreFoundation as CF
def getUrlFromLocalFileID(self, localFileID):
localFileQString = QString(localFileID.toLocalFile())
relCFStringRef = CF.CFStringCreateWithCString(
CF.kCFAllocatorDefault,
localFileQString.toUtf8(),
CF.kCFStringEncodingUTF8
)
relCFURL = CF.CFURLCreateWithFileSystemPath(
CF.kCFAllocatorDefault,
relCFStringRef,
CF.kCFURLPOSIXPathStyle,
False # is directory
)
absCFURL = CF.CFURLCreateFilePathURL(
CF.kCFAllocatorDefault,
relCFURL,
objc.NULL
)
return QUrl(str(absCFURL[0])).toLocalFile()
To see this working in a drag and drop situation, see below:
import sys
import objc
import CoreFoundation as CF
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MyListWidget(QListWidget):
def __init__(self, parent):
super(MyListWidget, self).__init__(parent)
self.setAcceptDrops(True)
self.setDragDropMode(QAbstractItemView.InternalMove)
def getUrlFromLocalFileID(self, localFileID):
localFileQString = QString(localFileID.toLocalFile())
relCFStringRef = CF.CFStringCreateWithCString(
CF.kCFAllocatorDefault,
localFileQString.toUtf8(),
CF.kCFStringEncodingUTF8
)
relCFURL = CF.CFURLCreateWithFileSystemPath(
CF.kCFAllocatorDefault,
relCFStringRef,
CF.kCFURLPOSIXPathStyle,
False # is directory
)
absCFURL = CF.CFURLCreateFilePathURL(
CF.kCFAllocatorDefault,
relCFURL,
objc.NULL
)
return QUrl(str(absCFURL[0])).toLocalFile()
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.acceptProposedAction()
else:
super(MyListWidget, self).dragEnterEvent(event)
def dragMoveEvent(self, event):
super(MyListWidget, self).dragMoveEvent(event)
def dropEvent(self, event):
if event.mimeData().hasUrls():
event.setDropAction(Qt.CopyAction)
event.accept()
links = []
for url in event.mimeData().urls():
if QString(url.toLocalFile()).startsWith('/.file/id='):
url = self.getUrlFromLocalFileID(url)
links.append(url)
else:
links.append(str(url.toLocalFile()))
for link in links:
self.addItem(link)
else:
super(MyListWidget,self).dropEvent(event)
class MyWindow(QWidget):
def __init__(self):
super(MyWindow,self).__init__()
self.setGeometry(100,100,300,400)
self.setWindowTitle("Filenames")
self.list = MyListWidget(self)
layout = QVBoxLayout(self)
layout.addWidget(self.list)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle("plastique")
window = MyWindow()
window.show()
sys.exit(app.exec_())
I'm trying to make a function that runs a ttk progressbar until a file is created. It seems that Widget.after is causing the APPCRASH but I don't know why. Please help!
def FilePgBar(title, file):
if root:
root.withdraw()
boxRoot = Toplevel(master=root)
boxRoot.withdraw()
else:
boxRoot = Tk()
boxRoot.withdraw()
boxRoot.protocol('WM_DELETE_WINDOW', denyWindowManagerClose )
boxRoot.title(title)
boxRoot.iconname('Dialog')
boxRoot.geometry(rootWindowPosition)
boxRoot.minsize(400, 100)
pgBar = ttk.Progressbar(boxRoot, orient=HORIZONTAL, length=300, mode='indeterminate')
pgBar.grid(row=1, column=0)
pgBar.pack()
pgBar.start()
def checkfile():
if os.path.exists(file):
pgBar.stop()
pgBar.destroy()
boxRoot.deiconify()
boxRoot.mainloop()
boxRoot.destroy()
if root: root.deiconify()
else:
boxRoot.after(100, checkfile)
checkfile()
I want to call this function from others scripts, so I'm not sure about using a class
EDIT: I edited the code. I no longer get an APPCRASH, but nothing happens when I run the program.
Python evaluates the arguments before passing them to a function. So when it encounters
boxRoot.after(100, checkfile(file))
it evaluates checkfile(file) -- calling checkfile -- and replaces checkfile(file) with the value returned by the function before calling boxRoot.after.
Since checkfile(file) has no return statement, None is returned by default. Thus
boxRoot.after(100, None)
gets called. This raises an error since the second argument to boxRoot.after should be a callable.
Instead, pass the function object checkfile itself:
def checkfile():
if os.path.exists(file):
pgBar.stop()
pgBar.destroy()
boxRoot.destroy()
if root: root.deiconify()
else:
# You need to update the progress bar
boxRoot.after(100, checkfile)
This allows the boxRoot.after function to call the function from within boxRoot.after instead of before after is called.
You might do something like this:
import os
import Tkinter as tk
import ttk
class App(object):
def __init__(self, master, *args, **kwargs):
self.master = master
self.button = tk.Button(master, text='Stop', command=self.stop)
self.button.pack()
self.progress = ttk.Progressbar(master, orient="horizontal",
length=200, mode="determinate")
self.progress.pack()
self.progress["value"] = 0
self.progress["maximum"] = 100
self.filename = '/tmp/out'
if os.path.exists(self.filename):
os.unlink(self.filename)
self.checkfile()
def checkfile(self):
self.progress["value"] += 1
if (not os.path.exists(self.filename)
and self.progress["value"] < self.progress["maximum"]):
self.master.after(100, self.checkfile)
def stop(self):
with open(self.filename, 'w') as f: pass
root = tk.Tk()
app = App(root)
root.mainloop()
I'm trying this:
import os, sys
from Gui import *
import Image as PIL
import ImageTk
class ImageBrowser(Gui):
def __init__(self):
Gui.__init__(self)
self.button = self.bu(command=self.quit, relief=FLAT)
def image_loop(self, dirname='.'):
files = os.listdir(dirname)
for file in files:
try:
self.show_image(file)
print (file)
self.mainloop()
except IOError:
continue
except:
break
def show_image(self, filename):
image = PIL.open(filename)
self.tkpi = ImageTk.PhotoImage(image)
self.button.config(image=self.tkpi)
def main(script, dirname='.'):
g = ImageBrowser()
g.image_loop(dirname)
if __name__ == '__main__':
main(*sys.argv)
I'm getting an error that says:
from Gui import *
ImportError: No module named Gui
I'm assuming "from Gui import *" doesn't work in python 3, does anyone know how to do this in python 3? Thank you so much (:
If you are talking about the Gui module that comes with Swampy, then
in order to use Gui with Python3, you'll need to install the Python3 version of Swampy.