Posts: 48
Threads: 8
Joined: Feb 2019
Feb-28-2019, 05:30 AM
(This post was last modified: Feb-28-2019, 05:32 AM by jttolleson.)
HELLO,
My name is Jayson,
I am new to this forum and thought it would unravel my issue:
A web based GUI in a python script???
I always need to attach a display by the end and I cannot get through...
HERE WE GO:
I have a website on a gcloud ubuntu 18 virtual machine (g1). https://35.236.122.135
The site is slung from a webserver on port 443 for webrtc with cgi via https://35.236.122.135/webserver3.py
In https://35.236.122.135/cgi-bin/ I run python scripts, also deeper
In https://35.236.122.135/cgi-bin/lftr/music/ I have 4 scripts that are relevant
1: https://35.236.122.135/cgi-bin/lftr/musi..._PLAYER.py
2: https://35.236.122.135/cgi-bin/lftr/musi...D_AUDIO.py
3: https://35.236.122.135/cgi-bin/lftr/musi...TO_MIDI.py
4: https://35.236.122.135/cgi-bin/lftr/music/PLAY_MIDI.py
They are not just up, they will run in position.
Also. now. when I run it by going to https://35.236.122.135/cgi-bin/lftr/musi..._PLAYER.py ; or cd /var/www/cgi-bin/lftr/music then sudo python3 AUDIO_TO_MIDI_PLAYER.py
I GET MY ERROR: NO DISPLAY for the website
"Unable to access the X Display, is $DISPLAY set Properly?"
would anyone be able to assist me in my quest to have this work?...
Posts: 12,030
Threads: 485
Joined: Sep 2016
First url is not secure. didn't attempt anymore.
Post code here in code tags see: BBcode
Posts: 48
Threads: 8
Joined: Feb 2019
Ok...will do...jayt. I have a self signed cert for my webserver to get https and run webrtc.
Anyway...the files. On Linux in the structure outlined in the first post:
webserver3.py
import os, sys
from http.server import HTTPServer, CGIHTTPRequestHandler
import ssl
webdir = '/var/www/'
port = 443
os.chdir(webdir)
srvaddr=('', port)
srvobj = HTTPServer(srvaddr, CGIHTTPRequestHandler)
srvobj.socket = ssl.wrap_socket (srvobj.socket, keyfile='/var/security/35.236.122.135.key', certfile='/var/security/35.236.122.135.crt', server_side=True)
CGIHTTPRequestHandler.have_fork=False # Force the use of a subprocess
srvobj.serve_forever() 1:AUDIO_TO_MIDI_PLAYER.py #!usr/bin/env python3
import cgitb
cgitb.enable
import os
import wx
import os
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Launch Scripts")
panel = wx.Panel(self, wx.ID_ANY)
sizer = wx.BoxSizer(wx.VERTICAL)
buttonA = wx.Button(panel, id=wx.ID_ANY, label="App A", name="GETandUPLOAD_AUDIO")
buttonB = wx.Button(panel, id=wx.ID_ANY, label="App B", name="CONVERT_AUDIO_TO_MIDI")
buttonC = wx.Button(panel, id=wx.ID_ANY, label="App C", name="PLAY_MIDI")
buttons = [buttonA, buttonB, buttonC]
for button in buttons:
self.buildButtons(button, sizer)
panel.SetSizer(sizer)
def buildButtons(self, btn, sizer):
btn.Bind(wx.EVT_BUTTON, self.onButton)
sizer.Add(btn, 0, wx.ALL, 5)
def onButton(self, event):
button = event.GetEventObject()
os.system('python {}.py'.format(button.GetName()))
button_id = event.GetId()
button_by_id = self.FindWindowById(button_id)
print ("The button you pressed was labeled: " + button_by_id.GetLabel())
print ("The button's name is " + button_by_id.GetName())
# Run the program
if __name__ == "__main__":
app = wx.App(False)
frame = MyForm()
frame.Show()
app.MainLoop()
print ('''Content-Type: text/html''')
print
print ('''<html>
<?php ?>
<html>
<head>
<meta charset="UTF-8">
<title>MUSIC - audio to midi player</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<style>* {
padding: 0;
margin: 0;
}
a {
color: #337ab7;
}
p {
margin-top: 1rem;
}
a:hover {
color:#23527c;
}
a:visited {
color: #8d75a3;
}
body {
margin: 1rem;
padding: 1rem;
font-family: sans-serif;
max-width: 28rem;
margin: 0 auto;
position: relative;
}
#controls {
display: flex;
margin-top: 2rem;
}
button {
flex-grow: 1;
height: 2.5rem;
min-width: 2rem;
border: none;
border-radius: 0.15rem;
background: #ed341d;
margin-left: 2px;
box-shadow: inset 0 -0.15rem 0 rgba(0, 0, 0, 0.2);
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
color:#ffffff;
font-weight: bold;
font-size: 1rem;
}
button:hover, button:focus {
outline: none;
background: #c72d1c;
}
button::-moz-focus-inner {
border: 0;
}
button:active {
box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.2);
line-height: 3rem;
}
button:disabled {
pointer-events: none;
background: lightgray;
}
button:first-child {
margin-left: 0;
}
audio {
display: block;
width: 100%;
margin-top: 0.2rem;
}
li {
list-style: none;
margin-bottom: 1rem;
}
#formats {
margin-top: 0.5rem;
font-size: 80%;
}
</style>''') 2: GETandUPLOAD_AUDIO.py
#!usr/bin/env python3
import cgitb
cgitb.enable
print ('''Content-Type: text/html''')
print
print ('''<html>
<html>
<body>
<h1>RECORD AUDIO .wav to convert to midi</h1>
<div id="controls">
<button id="recordButton">Record</button>
<button id="pauseButton" disabled>Pause</button>
<button id="stopButton" disabled>Stop</button>
</div>
<div id="formats">Format: start recording to see sample rate</div>
<h3>Recordings</h3>
<ol id="recordingsList"></ol>
<script src="https://cdn.rawgit.com/mattdiamond/Recorderjs/08e7abd9/dist/recorder.js"></script>
<script>URL = window.URL || window.webkitURL;
var gumStream; //stream from getUserMedia()
var rec; //Recorder.js object
var input; //MediaStreamAudioSourceNode we'll be recording
// shim for AudioContext when it's not avb.
var AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext //audio context to help us record
var recordButton = document.getElementById("recordButton");
var stopButton = document.getElementById("stopButton");
var pauseButton = document.getElementById("pauseButton");
//add events to those 2 buttons
recordButton.addEventListener("click", startRecording);
stopButton.addEventListener("click", stopRecording);
pauseButton.addEventListener("click", pauseRecording);
function startRecording() {
console.log("recordButton clicked");
/*
Simple constraints object, for more advanced audio features see
https://addpipe.com/blog/audio-constraints-getusermedia/
*/
var constraints = { audio: true, video:false }
/*
Disable the record button until we get a success or fail from getUserMedia()
*/
recordButton.disabled = true;
stopButton.disabled = false;
pauseButton.disabled = false
/*
We're using the standard promise based getUserMedia()
https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
*/
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
console.log("getUserMedia() success, stream created, initializing Recorder.js ...");
/*
create an audio context after getUserMedia is called
sampleRate might change after getUserMedia is called, like it does on macOS when recording through AirPods
the sampleRate defaults to the one set in your OS for your playback device
*/
audioContext = new AudioContext();
//update the format
document.getElementById("formats").innerHTML="Format: 1 channel pcm @ "+audioContext.sampleRate/1000+"kHz"
/* assign to gumStream for later use */
gumStream = stream;
/* use the stream */
input = audioContext.createMediaStreamSource(stream);
/*
Create the Recorder object and configure to record mono sound (1 channel)
Recording 2 channels will double the file size
*/
rec = new Recorder(input,{numChannels:1})
//start the recording process
rec.record()
console.log("Recording started");
}).catch(function(err) {
//enable the record button if getUserMedia() fails
recordButton.disabled = false;
stopButton.disabled = true;
pauseButton.disabled = true
});
}
function pauseRecording(){
console.log("pauseButton clicked rec.recording=",rec.recording );
if (rec.recording){
//pause
rec.stop();
pauseButton.innerHTML="Resume";
}else{
//resume
rec.record()
pauseButton.innerHTML="Pause";
}
}
function stopRecording() {
console.log("stopButton clicked");
//disable the stop button, enable the record too allow for new recordings
stopButton.disabled = true;
recordButton.disabled = false;
pauseButton.disabled = true;
//reset button just in case the recording is stopped while paused
pauseButton.innerHTML="Pause";
//tell the recorder to stop the recording
rec.stop();
//stop microphone access
gumStream.getAudioTracks()[0].stop();
//create the wav blob and pass it on to createDownloadLink
rec.exportWAV(createDownloadLink);
}
function createDownloadLink(blob) {
var url = URL.createObjectURL(blob);
var au = document.createElement('audio');
var li = document.createElement('li');
var link = document.createElement('a');
//name of .wav file to use during upload and download (without extendion)
var filename = 'Recording';
//add controls to the <audio> element
au.controls = true;
au.src = url;
//save to disk link
link.href = url;
link.download = filename+".wav"; //download forces the browser to donwload the file using the filename
link.innerHTML = "Save to disk";
//add the new audio element to li
li.appendChild(au);
//add the filename to the li
li.appendChild(document.createTextNode(filename+".wav "))
//add the save to disk link to li
li.appendChild(link);
//upload link
var upload = document.createElement('a');
upload.href="#";
upload.innerHTML = "Upload";
upload.addEventListener("click", function(event){
var xhr=new XMLHttpRequest();
xhr.onload=function(e) {
if(this.readyState === 4) {
console.log("Server returned: ",e.target.responseText);
}
};
var fd=new FormData();
fd.append("audio_data",blob, filename);
xhr.open("POST","upload.php",true);
xhr.send(fd);
})
li.appendChild(document.createTextNode (" "))//add a space in between
li.appendChild(upload)//add the upload link to li
//add the li element to the ol
recordingsList.appendChild(li);
}</script>
</body>
</html>''')
print ('''''')
print ('''''')
print ('''''')
print ('''''')
print ('''<html><h1>Directory Listing:</h1></html>''')
print ('''<html><h1>/var/www/cgi-bin/lftr/</h1></html>''')
print ('''<html><h1>[music][audio][midi]</h1></html>''')
folder = os.listdir("/var/www/cgi-bin/lftr/music/")
audiofolder = os.listdir("/var/www/cgi-bin/lftr/music/audio")
midifolder = os.listdir("/var/www/cgi-bin/lftr/music/midi")
print ('''''')
print ('''''')
print ('''''')
print ('''''')
print (folder)
print (audiofolder)
print (midifolder) 3: CONVERT_AUDIO_TO_MIDI.py
#!usr/bin/env python3
import cgitb
cgitb.enable
print ('''Content-Type: text/html''')
print
print ('''<html>
</html>''')
print ('''''')
print ('''''')
print ('''''')
print ('''''')
print ('''<html><h1>Directory Listing:</h1></html>''')
print ('''<html><h1>/var/www/cgi-bin/lftr/</h1></html>''')
print ('''<html><h1>[music][audio][midi]</h1></html>''')
folder = os.listdir("/var/www/cgi-bin/lftr/music/")
audiofolder = os.listdir("/var/www/cgi-bin/lftr/music/audio")
midifolder = os.listdir("/var/www/cgi-bin/lftr/music/midi")
print ('''''')
print ('''''')
print ('''''')
print ('''''')
print (folder)
print (audiofolder)
print (midifolder)
print ('''''')
print ('''''')
print ('''''')
print ('''''')
print ('''''')
print ('''''')
print ('''''')
print ('''''')
# CREATED: 11/9/15 3:57 PM by Justin Salamon <[email protected]>
import librosa
import vamp
import argparse
import os
import numpy as np
from midiutil.MidiFile import MIDIFile
from scipy.signal import medfilt
import jams
import __init__
'''
Extract the melody from an audio file and convert it to MIDI.
The script extracts the melody from an audio file using the Melodia algorithm,
and then segments the continuous pitch sequence into a series of quantized
notes, and exports to MIDI using the provided BPM. If the --jams option is
specified the script will also save the output as a JAMS file. Note that the
JAMS file uses the original note onset/offset times estimated by the algorithm
and ignores the provided BPM value.
Note: Melodia can work pretty well and is the result of several years of
research. The note segmentation/quantization code was hacked in about 30
minutes. Proceed at your own risk... :)
usage: audio_to_midi_melodia.py [-h] [--smooth SMOOTH]
[--minduration MINDURATION] [--jams]
infile outfile bpm
Examples:
python audio_to_midi_melodia.py --smooth 0.25 --minduration 0.1 --jams
~/song.wav ~/song.mid 60
'''
def save_jams(jamsfile, notes, track_duration, orig_filename):
# Construct a new JAMS object and annotation records
jam = jams.JAMS()
# Store the track duration
jam.file_metadata.duration = track_duration
jam.file_metadata.title = orig_filename
midi_an = jams.Annotation(namespace='pitch_midi',
duration=track_duration)
midi_an.annotation_metadata = \
jams.AnnotationMetadata(
data_source='audio_to_midi_melodia.py v%s' % __init__.__version__,
annotation_tools='audio_to_midi_melodia.py (https://github.com/'
'justinsalamon/audio_to_midi_melodia)')
# Add midi notes to the annotation record.
for n in notes:
midi_an.append(time=n[0], duration=n[1], value=n[2], confidence=0)
# Store the new annotation in the jam
jam.annotations.append(midi_an)
# Save to disk
jam.save(jamsfile)
def save_midi(outfile, notes, tempo):
track = 0
time = 0
midifile = MIDIFile(1)
# Add track name and tempo.
midifile.addTrackName(track, time, "MIDI TRACK")
midifile.addTempo(track, time, tempo)
channel = 0
volume = 100
for note in notes:
onset = note[0] * (tempo/60.)
duration = note[1] * (tempo/60.)
# duration = 1
pitch = note[2]
midifile.addNote(track, channel, pitch, onset, duration, volume)
# And write it to disk.
binfile = open(outfile, 'wb')
midifile.writeFile(binfile)
binfile.close()
def midi_to_notes(midi, fs, hop, smooth, minduration):
# smooth midi pitch sequence first
if (smooth > 0):
filter_duration = smooth # in seconds
filter_size = int(filter_duration * fs / float(hop))
if filter_size % 2 == 0:
filter_size += 1
midi_filt = medfilt(midi, filter_size)
else:
midi_filt = midi
# print(len(midi),len(midi_filt))
notes = []
p_prev = None
duration = 0
onset = 0
for n, p in enumerate(midi_filt):
if p == p_prev:
duration += 1
else:
# treat 0 as silence
if p_prev > 0:
# add note
duration_sec = duration * hop / float(fs)
# only add notes that are long enough
if duration_sec >= minduration:
onset_sec = onset * hop / float(fs)
notes.append((onset_sec, duration_sec, p_prev))
# start new note
onset = n
duration = 1
p_prev = p
# add last note
if p_prev > 0:
# add note
duration_sec = duration * hop / float(fs)
onset_sec = onset * hop / float(fs)
notes.append((onset_sec, duration_sec, p_prev))
return notes
def hz2midi(hz):
# convert from Hz to midi note
hz_nonneg = hz.copy()
idx = hz_nonneg <= 0
hz_nonneg[idx] = 1
midi = 69 + 12*np.log2(hz_nonneg/440.)
midi[idx] = 0
# round
midi = np.round(midi)
return midi
def audio_to_midi_melodia(infile, outfile, bpm, smooth=0.25, minduration=0.1,
savejams=False):
# define analysis parameters
fs = 44100
hop = 128
# load audio using librosa
print("Loading audio...")
data, sr = librosa.load(infile, sr=fs, mono=True)
# extract melody using melodia vamp plugin
print("Extracting melody f0 with MELODIA...")
melody = vamp.collect(data, sr, "mtg-melodia:melodia",
parameters={"voicing": 0.2})
# hop = melody['vector'][0]
pitch = melody['vector'][1]
# impute missing 0's to compensate for starting timestamp
pitch = np.insert(pitch, 0, [0]*8)
# debug
# np.asarray(pitch).dump('f0.npy')
# print(len(pitch))
# convert f0 to midi notes
print("Converting Hz to MIDI notes...")
midi_pitch = hz2midi(pitch)
# segment sequence into individual midi notes
notes = midi_to_notes(midi_pitch, fs, hop, smooth, minduration)
# save note sequence to a midi file
print("Saving MIDI to disk...")
save_midi(outfile, notes, bpm)
if savejams:
print("Saving JAMS to disk...")
jamsfile = outfile.replace(".mid", ".jams")
track_duration = len(data) / float(fs)
save_jams(jamsfile, notes, track_duration, os.path.basename(infile))
print("Conversion complete.")
if __name__ == "__main__":
audio_to_midi_melodia(Recording.wav, Recording.mid, 87,
smooth=.25, minduration=.2) 4: PLAY_MIDI.py
#!usr/bin/env python3
import cgitb
cgitb.enable
import mido
msg = mido.Message('note_on", note=60)
msg.type
msg.note
msg.bytes()
msg.copy(channel=2)
port = mido.open_output('Port Name')
port.send(msg)
with mido.open_input() as inport:
for msg in inport:
print(msg)
mid = mido.MidiFile('Recording.mid')
for msg in mid.play():
port.send(msg) I know I have some work to do but the concept is hurt too
Posts: 48
Threads: 8
Joined: Feb 2019
While there are other errors the main issue still stands with script 1: AUDIO_TO_MIDI_PLAYER.py. When it runs it doesn't have a display.....
Posts: 12,030
Threads: 485
Joined: Sep 2016
I have set up an environment and will see If I can be of service, no promises, and it will take some time to familiarize myself with your code.
I won't be able to run though because even though I have what is supposed to be a good install of wxpython on my Linux Mint environment, I haven't been able to successfully use it. I am quite familiar with the phoenix version and have used it extensively on MS windows, but not here.
I don't expect I will respond again on this until some time tomorrow.
Perhaps someone else in a better position to help will respond before then.
Posts: 48
Threads: 8
Joined: Feb 2019
Yes...it was some hours of compiling on a g1 for wxPython Phoenix in ubuntu18 I used pip3 install mostly
Posts: 48
Threads: 8
Joined: Feb 2019
I suppose I am looking for a Display Back-end. Similar to GTK's Broadwayd. https://developer.gnome.org/gtk3/stable/broadwayd.html
Through my research i have found ipython and it may be relevent if i rewrite my script some.
https://ipython.org/ipython-doc/3/intera...th-ipython
Posts: 12,030
Threads: 485
Joined: Sep 2016
I stopped playing this after mucking around once again, trying to get wxpython to install properly.
It installs, but is not usable.
Posts: 48
Threads: 8
Joined: Feb 2019
Mar-03-2019, 06:10 AM
(This post was last modified: Mar-03-2019, 06:39 AM by jttolleson.)
Yes, Hello again ---Jayson:
wxPython will work in with IPython in Python3. Especially, in deb or ubuntu
and this will be my direction, however the same problem exists. My x-display in web.
I will post again as this thread continues, with a simple script that will have the same issue. the x display.
Ok, well here we go: IPython
sudo nohup python3 /var/www/webserver3.py &
import os, sys
from http.server import HTTPServer, CGIHTTPRequestHandler
import ssl
webdir = '/var/www/'
port = 443
os.chdir(webdir)
srvaddr=('', port)
srvobj = HTTPServer(srvaddr, CGIHTTPRequestHandler)
srvobj.socket = ssl.wrap_socket (srvobj.socket, keyfile='/var/security/35.236.122.135.key', certfile='/var/security/35.236.122.135.crt', server_side=True)
CGIHTTPRequestHandler.have_fork=False # Force the use of a subprocess
srvobj.serve_forever() sudo python3 /var/www/cgi-bin/lftr/wxgui.py
#!/usr/bin/env python3
import cgitb
cgitb.enable
"""
A Simple wx example to test IPython's event loop integration.
To run this do:
In [5]: %gui wx # or start IPython with '--gui wx'
In [6]: %run gui-wx.py
Ref: Modified from wxPython source code wxPython/samples/simple/simple.py
"""
import wx
class MyFrame(wx.Frame):
"""
This is MyFrame. It just shows a few controls on a wxPanel,
and has a simple menu.
"""
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title,
pos=(150, 150), size=(350, 200))
# Create the menubar
menuBar = wx.MenuBar()
# and a menu
menu = wx.Menu()
# add an item to the menu, using \tKeyName automatically
# creates an accelerator, the third param is some help text
# that will show up in the statusbar
menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample")
# bind the menu event to an event handler
self.Bind(wx.EVT_MENU, self.OnTimeToClose, id=wx.ID_EXIT)
# and put the menu on the menubar
menuBar.Append(menu, "&File")
self.SetMenuBar(menuBar)
self.CreateStatusBar()
# Now create the Panel to put the other controls on.
panel = wx.Panel(self)
# and a few controls
text = wx.StaticText(panel, -1, "Hello World!")
text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
text.SetSize(text.GetBestSize())
btn = wx.Button(panel, -1, "Close")
funbtn = wx.Button(panel, -1, "Just for fun...")
# bind the button events to handlers
self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, btn)
self.Bind(wx.EVT_BUTTON, self.OnFunButton, funbtn)
# Use a sizer to layout the controls, stacked vertically and with
# a 10 pixel border around each
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(text, 0, wx.ALL, 10)
sizer.Add(btn, 0, wx.ALL, 10)
sizer.Add(funbtn, 0, wx.ALL, 10)
panel.SetSizer(sizer)
panel.Layout()
def OnTimeToClose(self, evt):
"""Event handler for the button click."""
print("See ya later!")
self.Close()
def OnFunButton(self, evt):
"""Event handler for the button click."""
print("Having fun yet?")
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, "Simple wxPython App")
self.SetTopWindow(frame)
print("Print statements go to this stdout window by default.")
frame.Show(True)
return True
if __name__ == '__main__':
app = wx.GetApp()
if app is None:
app = MyApp(redirect=False, clearSigInt=False)
else:
frame = MyFrame(None, "Simple wxPython App")
app.SetTopWindow(frame)
print("Print statements go to this stdout window by default.")
frame.Show(True)
try:
from IPython.lib.inputhook import enable_gui
enable_gui('wx', app)
except ImportError:
app.MainLoop() now this code: will run IPython in a .py script on the cgi-server
#!/usr/bin/env python3
import cgitb
cgitb.enable
import IPython
IPython.start_ipython(argv=[])
I hope we still can have an open mind about this being fun and useful structure to run interactive web gui scripting which would be a PLUS...
and this becomes a complicated question: b/c sudo IPython /var/www/cgi-bin/lftr/wxgui.py --gui=wx
can be run as something like this: sudo python3 /var/www/cgi-bin/lftr/wxgui.py if it is including some IPython ----
#!/usr/bin/env python3
import cgitb
cgitb.enable
import IPython
IPython.start_ipython(argv=[]) # this will start IPython, however i am unsure how to input the entire script
import IPython.display #this will access display for a gui of wx hopefully
gui=wx #incorrect code
import wx
class MyFrame(wx.Frame):
"""
This is MyFrame. It just shows a few controls on a wxPanel,
and has a simple menu.
"""
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title,
pos=(150, 150), size=(350, 200))
# Create the menubar
menuBar = wx.MenuBar()
# and a menu
menu = wx.Menu()
# add an item to the menu, using \tKeyName automatically
# creates an accelerator, the third param is some help text
# that will show up in the statusbar
menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample")
# bind the menu event to an event handler
self.Bind(wx.EVT_MENU, self.OnTimeToClose, id=wx.ID_EXIT)
# and put the menu on the menubar
menuBar.Append(menu, "&File")
self.SetMenuBar(menuBar)
self.CreateStatusBar()
# Now create the Panel to put the other controls on.
panel = wx.Panel(self)
# and a few controls
text = wx.StaticText(panel, -1, "Hello World!")
text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
text.SetSize(text.GetBestSize())
btn = wx.Button(panel, -1, "Close")
funbtn = wx.Button(panel, -1, "Just for fun...")
# bind the button events to handlers
self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, btn)
self.Bind(wx.EVT_BUTTON, self.OnFunButton, funbtn)
# Use a sizer to layout the controls, stacked vertically and with
# a 10 pixel border around each
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(text, 0, wx.ALL, 10)
sizer.Add(btn, 0, wx.ALL, 10)
sizer.Add(funbtn, 0, wx.ALL, 10)
panel.SetSizer(sizer)
panel.Layout()
def OnTimeToClose(self, evt):
"""Event handler for the button click."""
print("See ya later!")
self.Close()
def OnFunButton(self, evt):
"""Event handler for the button click."""
print("Having fun yet?")
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, "Simple wxPython App")
self.SetTopWindow(frame)
print("Print statements go to this stdout window by default.")
frame.Show(True)
return True
if __name__ == '__main__':
app = wx.GetApp()
if app is None:
app = MyApp(redirect=False, clearSigInt=False)
else:
frame = MyFrame(None, "Simple wxPython App")
app.SetTopWindow(frame)
print("Print statements go to this stdout window by default.")
frame.Show(True)
try:
from IPython.lib.inputhook import enable_gui
enable_gui('wx', app)
except ImportError:
app.MainLoop() anyone? - - - for a round of direction or help??? i still get the display error no matter what
so I set the Display Environment variable to localhost:0 with no noticible effect.
Posts: 48
Threads: 8
Joined: Feb 2019
I suppose I am now working on an x display....so ipython will function for me:
This is generally what I will start with and try to bring back an update:
export DISPLAY=:1
Xvfb :1 -screen 0 1600x1200x16 -fbdir /var/tmp &
x11vnc -rfbport 443 -display :1 -bg -nopw -listen localhost -xkb
I hope more research will move me forward.
|