Spyder never "quits" - user-interface

I loaded up Anaconda and realized there is more stuff there than I can absorb in my lifetime. However, I did load Spyder and pasted in a working program that runs without error in PyCharm and Thonny.
"""Create a 2 button window"""
import tkinter as tk
from tkinter import *
from tkinter import messagebox
#write slogan out in a message box
def write_slogan():
messagebox.showinfo("our message",
"tkinter is easy to use")
#set up the window
root = tk.Tk() #get the window
root.geometry("100x100+300+300") #x, y window size and position
#create Hello button
slogan = Button(root,
text="Hello",
command=write_slogan)
slogan.pack(side=LEFT, padx=10)
#create exit button with red letters
button = Button(root,
text="QUIT",
fg="red",
command=quit)
button.pack(side=RIGHT, padx=10)
#start running the tkinter loop
root.mainloop()
It may not surprise Spyder mavens, but I was surprised to see that it did not recognize "quit" However, I replaced it with
command=sys.exit
and that at least compiled.
However, when I ran it, the window appeared UNDER the Spyder window. I found it in the task bar. BUT, when I clicked in the Quit button, the program just hung. I had to go to the console and and type
quit
to stop the process.
I guess Spyder isn't really intended for GUI programming.

Related

Tkinter askopenfilename() won't close if destroy followed by an input

I can't get a Tkinter file dialog box to close. This Tkinter file dialog box closes just fine if there is no input statement downstream. But with it, it does not close, and crashes the app.
Through a process of elimination, it seems input() downstream from the root.destroy() command is interfering with the window closing.
Anyone have a fix?
Here's the code:
import tkinter
from tkinter import filedialog
###### THIS CODE WORKS #########
# Make a top-level instance and hide since it is ugly and big.
root = tkinter.Tk()
root.withdraw()
# Make it almost invisible - no decorations, 0 size, top left corner.
root.overrideredirect(True)
root.geometry('0x0+0+0')
# Show window again and lift it to top so it can get focus,
# otherwise dialogs will end up behind the terminal.
root.deiconify()
root.lift()
root.focus_force()
# get the file path of the trades to load.
new_file_path = filedialog.askopenfilename()
# Get rid of the top-level instance once to make it actually invisible.
root.destroy()
###### WHEN INPUT IS ADDED IT DOESNT WORK######
input('Testing testing testing ')
I've tried adding a time.sleep(1) just after root.destroy.
I've tried the solution here:
Tkinter askopenfilename() won't close
I'm using OSX 10.11.4 with Pycharm.

How can I dynamically add actions to a QMenu while it is open on a Mac?

I have QSystemTrayIcon with a QMenu. In order to fill the menu, I need to fetch some things from the network, so I want to do that in the background.
So I have a QThread with a slot that is connected to the activated signal of the tray icon. Then the thread fetches the resources and updates the menu using another signal.
However, these updates do not show until I close and reopen the menu.
This seems to be a Mac specific problem. I ran my code on Windows, and there it updated more or less correctly. Is there any workaround?
Below is an extracted version of the problem. When the menu is opened, it will sleep 1 second in a thread and then change the menu. This change is not seen.
import sys
import time
from PySide import QtCore, QtGui
class PeerMenu(QtGui.QMenu):
def __init__(self):
QtGui.QMenu.__init__(self)
self.set_peers("prestine")
#QtCore.Slot(object)
def set_peers(self, label):
self.clear()
self.addAction(QtGui.QAction(label, self))
self.addSeparator()
self.addAction(QtGui.QAction("Hello", self))
class GUIListener(QtCore.QObject):
files = QtCore.Signal(object)
def __init__(self):
QtCore.QObject.__init__(self)
self.counter = 0
#QtCore.Slot()
def check(self):
time.sleep(1)
self.counter += 1
self.files.emit(str(self.counter))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
icon = QtGui.QSystemTrayIcon(QtGui.QIcon('images/glyphicons-206-electricity.png'), app)
listener = GUIListener()
t = QtCore.QThread()
t.start()
listener.moveToThread(t)
menu = PeerMenu()
icon.activated.connect(listener.check)
listener.files.connect(menu.set_peers)
icon.setContextMenu(menu)
icon.show()
app.exec_()
After a few hours of extensive googling I finally figured it out.
You can create a borderless window using QtGui.QMainWindow(parent=None, flags=QtCore.Qt.Popup) and then find the location of the icon with icon.geometry().center() and finally move the window there with window.move(icon_point).
There is some hackery involved in deciding how to place the window relative to the icon. Full code can be found at https://github.com/pepijndevos/gierzwaluw/blob/master/gui.py

Run thread in main window for both Windows and Linux

I am creating a game to run inside a GUI (text area, button, menu etc) I've created a GUI with wxpython. I create a panel inside the main window, which runs a pygame thread.
Problem:
On Windows, the pygame thread runs perfectly inside the main window. But on Linux, the pygame pop up on a new window. How can I set this such that both windows and Linux run the thread in the main window?
Code:
class SDLPanel(wx.Panel):
def __init__(self,parent,ID,tplSize):
global pygame
global pygame_init_flag
wx.Panel.__init__(self, parent, ID, size=tplSize)
self.Fit()
if (sys.platform == 'win32'):
os.environ['SDL_WINDOWID'] = str(self.GetHandle())
os.environ['SDL_VIDEODRIVER'] = 'windib'
else:
os.environ['SDL_VIDEODRIVER'] = 'x11'
#here is where things change if pygame has already been initialized
#we need to do so again
if pygame_init_flag:
#call pygame.init() on subsaquent windows
pygame.init()
else:
#import if this is the first time
import pygame
pygame_init_flag = True #make sure we know that pygame has been imported
pygame.display.init()
window = pygame.display.set_mode(tplSize)
self.thread = SDLThread(window)
self.thread.Start()
def __del__(self):
self.thread.Stop()
print "thread stoped"
#very important line, this makes sure that pygame exits before we
#reinitialize it other wise we get errors
pygame.quit()
Solved problem.
In main window we must self.Show()
Idk why in linux the main window must be showed . Same code.
Tks all
This is a disclaimer alert, according to https://forums.libsdl.org/viewtopic.php?p=39332, the solution works only with SDL 1.2 and not 2.0.

Tkinter GUI doesn't work outside iPython

I'm rather unfamiliar with Python, but am attempting to make a simple gui with tkinter (Python 2.7.x). I have one fully functional button, but I can only get the script to work in iPython. When I try to run it outside of the iPython environment, I see some text run down the command prompt but nothing happens (ie no gui appears, no action happens).
My code:
import Tkinter
from Tkinter import *
import os
#define frame
root = Tk()
frame = Frame(root)
frame.pack()
#define buttons
button = Button(frame, text="Action", command= lambda: os.system("Action.py"))
button.pack(side=LEFT)
Add root.mainloop() to the end of your code.

wxWidgets dialog doesn't get a maximize box

I've got a wxPython (via wxGlade) app with a dialog that has wx.MAXIMIZE_BOX set in the style, but the maximize box doesn't appear when I run the app.
Here's a minimal program that exhibits the behavior:
#!/usr/bin/env python
import wx
class MyDialog(wx.Dialog):
def __init__(self, *args, **kwds):
kwds["style"] = wx.DEFAULT_DIALOG_STYLE|wx.MAXIMIZE_BOX
wx.Dialog.__init__(self, *args, **kwds)
self.SetTitle("dialog_1")
self.Layout()
if __name__ == "__main__":
app = wx.PySimpleApp(0)
wx.InitAllImageHandlers()
dialog_1 = MyDialog(None, -1, "")
app.SetTopWindow(dialog_1)
dialog_1.Show()
app.MainLoop()
Note that wx.MAXIMIZE_BOX is set, but when I run this program I don't get a maximize box on the dialog:
Is this a window manager issue?
Is there something I can do to make the maximize box show up? (My real dialog has a bunch of scrolled text from a log file and it's easier to click maximize than it is to manually resize to fill the screen.)
I'm using:
Linux (Ubuntu 10.04 LTS)
python-wxgtk, libwxgtk2.8-0, libwxbase2.8-0: 2.8.10.1-0ubuntu1.2
metacity: 1:2.30.1-0ubuntu1.1
I found this in the wxWidgets docs:
"Under Unix or Linux, MWM (the Motif Window Manager) or other window managers recognizing the MHM hints should be running for any of these styles ( including wxMAXIMIZE_BOX ) to have an effect."
So it sounds like it might well be a window manager issue.

Resources