how can we print the output of a code in gui , not in console? - user-interface

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!

Related

Scrapy works in shell but spider returns empty csv

I am learning Scrapy. Now I just try to scrapy items and when I call spider:
planefinder]# scrapy crawl planefinder -o /User/spider/planefinder/pf.csv -t csv
it shows tech information and no scraped content (Crawled 0 pages .... etc), and it returns an empty csv file.
The problem is when i test xpath in scrapy shell it works:
>>> from scrapy.selector import Selector
>>> sel = Selector(response)
>>> flights = sel.xpath("//div[#class='col-md-12'][1]/div/div/table//tr")
>>> items = []
>>> for flt in flights:
... item = flt.xpath("td[1]/a/#href").extract_first()
... items.append(item)
...
>>> items
The following is my planeFinder.py code:
# -*-:coding:utf-8 -*-
from scrapy.spiders import CrawlSpider
from scrapy.selector import Selector, HtmlXPathSelector
from planefinder.items import arr_flt_Item, dep_flt_Item
class planefinder(CrawlSpider):
name = 'planefinder'
host = 'https://planefinder.net'
start_url = ['https://planefinder.net/data/airport/PEK/']
def parse(self, response):
arr_flights = response.xpath("//div[#class='col-md-12'][1]/div/div/table//tr")
dep_flights = response.xpath("//div[#class='col-md-12'][2]/div/div/table//tr")
for flight in arr_flights:
arr_item = arr_flt_Item()
arr_flt_url = flight.xpath('td[1]/a/#href').extract_first()
arr_item['arr_flt_No'] = flight.xpath('td[1]/a/text()').extract_first()
arr_item['STA'] = flight.xpath('td[2]/text()').extract_first()
arr_item['From'] = flight.xpath('td[3]/a/text()').extract_first()
arr_item['ETA'] = flight.xpath('td[4]/text()').extract_first()
yield arr_item
Please before going to CrawlSpider please check the docs for Spiders, some of the issues I've found were:
Instead of host use allowed_domains
Instead of start_url use start_urls
It seem that the page needs to have some cookies set or maybe it's using some kind of basic anti-bot protection, and you need to land somewhere else first.
Try this (I've also changed a bit :
# -*-:coding:utf-8 -*-
from scrapy import Field, Item, Request
from scrapy.spiders import CrawlSpider, Spider
class ArrivalFlightItem(Item):
arr_flt_no = Field()
arr_sta = Field()
arr_from = Field()
arr_eta = Field()
class PlaneFinder(Spider):
name = 'planefinder'
allowed_domains = ['planefinder.net']
start_urls = ['https://planefinder.net/data/airports']
def parse(self, response):
yield Request('https://planefinder.net/data/airport/PEK', callback=self.parse_flight)
def parse_flight(self, response):
flights_xpath = ('//*[contains(#class, "departure-board") and '
'./preceding-sibling::h2[contains(., "Arrivals")]]'
'//tr[not(./th) and not(./td[#class="spacer"])]')
for flight in response.xpath(flights_xpath):
arrival = ArrivalFlightItem()
arr_flt_url = flight.xpath('td[1]/a/#href').extract_first()
arrival['arr_flt_no'] = flight.xpath('td[1]/a/text()').extract_first()
arrival['arr_sta'] = flight.xpath('td[2]/text()').extract_first()
arrival['arr_from'] = flight.xpath('td[3]/a/text()').extract_first()
arrival['arr_eta'] = flight.xpath('td[4]/text()').extract_first()
yield arrival
The problem here is not understanding correctly which "Spider" to use, as Scrapy offers different custom ones.
The main one, and the one you should be using is the simple Spider and not CrawlSpider, because CrawlSpider is used for a more deep and intensive search into forums, blogs, etc.
Just change the type of spider to:
from scrapy import Spider
class plane finder(Spider):
...
Check the value of ROBOTSTXT_OBEY in your settings.py file. By default it's set to True (but not when you run shell). Set it to False if you wan't to disobey robots.txt file.

How do I convert an osx fileid to a filepath [duplicate]

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_())

close pygtk dialog window after it was used

I am currently writing a wrapper for a small console program I wrote.
The c program needs a password string as input and because I intend to use it through dmenu and such, I'd like to use a little gtk entry box to enter that string.
However, I have to fork after I get the input (because I'm also handling clipboard stuff which needs deletion after some time) and the window simply won't close until the child process exits.
from subprocess import Popen, PIPE
from gi.repository import Gtk
import sys
import os
import time
import getpass
HELP_MSG = "foobar [options] <profile>"
class EntryDialog(Gtk.Dialog):
def run(self):
result = super(EntryDialog, self).run()
if result == Gtk.ResponseType.OK:
text = self.entry.get_text()
else:
text = None
return text
def __init__(self):
super(EntryDialog, self).__init__()
entry = Gtk.Entry()
entry.set_visibility(False)
entry.connect("activate",
lambda ent, dlg, resp:
dlg.response(resp),
self,
Gtk.ResponseType.OK)
self.vbox.pack_end(entry, True, True, 0)
self.vbox.show_all()
self.entry = entry
def get_pwd():
if sys.stdin.isatty():
return getpass.getpass()
else:
prompt = EntryDialog()
prompt.connect("destroy", Gtk.main_quit)
passwd = prompt.run()
prompt.destroy()
return passwd
The thought is, that it should close when I hit enter, but I'm pretty sure I'm doing something entirely wrong.
The script basically continues like this:
profile = argv[0]
pwd = get_pwd()
if pwd is None:
print(HELP_MSG)
sys.exit()
out = doStuff()
text_to_clipboard(out)
# now fork and sleep!
if os.fork():
sys.exit()
time.sleep(10)
clear_clipboard()
sys.exit(0)
I dropped the python wrapper and wrote it directly in c. However, for anyone having the same problem, the (untested) solution would be to add a function
def quit():
self.emit("destroy")
where 'self' is the dialog box - and connect that to the "activate" signal,
entry.connect("activate", quit)
so that the dialog widget emits the destroy signal as soon as the user hits Return and thus Gtk.main_quit gets called.
In c the content can be extracted nicely by specifying a GtkEntryBuffer and calling it's
gtk_entry_buffer_get_text()
I didn't find it right now, but there is probably an equivalent for pygtk available.

from Gui import * in python 3?

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.

exe file not running (cx_Freeze + PySide)

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"]

Resources