pyqt5 how to open new window and reopen old - python

Hello
I do not know what to do, the window (register.py) opens very well from login.py, but the window (login.py) does not not open since register.py.
What to do?
register.py
https://hastebin.com/oyoxoyemak.rb
login.py
https://hastebin.com/tanuhigome.rb
error code
error code if i remove
screen = app.primaryScreen()
size = screen.size()
print('Size: %d x %d' % (size.width(), size.height()))
rect = screen.availableGeometry()
print('Available: %d x %d' % (rect.width(), rect.height()))
self.window.move((rect.width() / 2) - 230, (rect.height() / 2) - 230)
error code 2

Both issues are related to the scope.
app is a local variable in both scripts, which exists only in the scope of the script that is running (the if __name__ == "__main__": line).
So, if you run login.py, app is available in its scope, but if you run register.py app exists only for it, but not in the login.py scope (since it was never created "there").
Since primaryScreen is a static function, you don't need a reference to the application instance (which you could get through QtWidgets.QApplication.instance(), anyway):
Just change that line to:
screen = QtWidgets.QApplication.primaryScreen()
In the second issue, the problem is similar: since you're running login.py, MainWindow_Register is never declared in register.py.
I have not a "simple" solution for that, as your approach is a bit confused.
First of all, it seems like you're trying to implent your program starting from the output of pyuic, and if that's the case you should really avoid it: write your own code and use the pyuic generated files as suggested in the documentation.
Then, whenever you have to face multiple related windows, it's better to avoid calling themselves "recursively", and use a single window (or better, a separate object, even a subclass of QApplication) as a "manager". This will make everything easier programmatically, avoiding redundant code, while decreasing the possibility of bugs.
In your case, you should probably always use the login window as a "starting point", then show the register one whenever necessary.

Related

Call a python script from a python script within the same context

There is a python script start_test.py.
There is a second python script siple_test.py.
# pseudo code:
start_test.py --calls--> subprocess(python.exe simple_test.py, args_simple_test[])
The python interpreter for both scripts is the same. So instead of opening a new instance, I want to run simple_test.py directly from start_test.py. I need to preserve the sys.args environment. A nice to have would be to actually enter following code section in simple_test.py:
# file: simple_test.py
if __name__ == '__main__':
some_test_function()
Most important is, that the way should be a universal one, not depending on the content of the simple_test.py.
This setup would provide two benefits:
The call is much less resource intensive
The whole stack of simple_test.py can be debugged with pycharm
So, how do I execute the call of a python script, from a python script, without starting a new subprocess?
"Executing a script" is a somewhat blurry term.
Typically the if __name__== "__main__": part does the argument (sys.argv) decoding and then calls a worker function with explicit parameters. For clarity: It should not do anything else, since this additional work can't be called without creating a new process causing all the overhead you are trying to avoid.
You simply bypass that and call this implementing routine directly.
So you end up with start_test.py containing something like:
from simple_test import worker
# ...
worker(typed_arg1, typed_arg2)

Call a function from main script in an imported file

Before I begin, I know there are many questions that sound a lot like this one, but my question is a little different... So here it is...
As the title may of suggested, I am trying to call a function defined in my main.py script in an imported module. However, this situation is a bit different than that of a circular import situation. I have been doing a lot with pygame recently, and decided that I was gonna make a module that contains classes for buttons, text, sounds, and so on. But I want this file to be generic so it can be used with any game or application I make. Buttons usually have draw functions and stuff like that, so I can easily pass those variables into the functions without problem. The problem comes when I get to the part where I want to check if the button is clicked, and if it is do something. I want to have it set up so that I can pass in a string argument for a command, and use the eval() command on it (python 2.7). However, it throws the error of the function not being defined. I know why this is, but I want to see if there is anything I can do to get around this issue to keep the module as "generic" as possible. Below is a basic set of code to help explain what I want to do.
module1.py
class Button(object):
def __init__(self,x=0,y=0,image=None,command=""):
self.x = x
self.y = y
self.image = image
self.command = command
"""
Image this part filled with draw commands and stuff...
These functions work perfectly fine
"""
#Now here is the issue - local is mouse position
def checkClick(self, local):
#If statments here to determine if mouse over button and
#if mouse is clicked... The part below fails
eval(self.command)
main.py
import module1
import pygame
def quitgame():
pygame.quit()
quit()
local = pygame.mouse.get_pos()
b = module1.Button(command="quitgame")
#At this point lets assume that the mouse is overtop the button and the
#following function in the button will run
b.checkClick(local)
The error, as I said before states that the function I try to call is not defined. I have found a workaround for this, so I don't want answers that tell me how I can change this so it does not take a command as input. I would like however, to make it so I can input a command as an argument. Maybe I am not inputing a command the way I should, but I would like to do it like this, especially because the tkinter module allows you to enter a command as input/a variable. Maybe there is not a way to do this like I wish, but I really want to keep this code as reusable as possible with no changing required between games, and I would rather not have to put this code into my games/applications every time I make them (like I said before the code example I gave was just an example, my actual button code is much larger than what I did above). Like I said before as well, I know that there are many questions that are just like this one, but they have not helped me at all with this issue. The others suggested using scripts that are imported as well which contain addition variables and such, but I would rather not do this. Also, I have a workaround that completely gets rid of the issue, but it is not nearly as neat or easy as this would be.
As always, any help would be appreciated and thanks ahead of time for your answers in case I don't get back to you right away.
I want to have it set up so that I can pass in a string argument for a command, and use the eval() command on it (python 2.7).
No, no, no. Pass it a function:
# In main.py
b = module1.Button(command=quitgame)
# In module1.py
def checkClick(self, local):
...
self.command()
eval is almost never the right tool for any job.
If you don't want to define a function just to pass it as a command parameter, you can use a lambda for short (single-expression) functions:
b = module1.Button(command=lambda: do_whatever(some, arguments))

Safe way to initialize a Plugin that depends on Project settings

I'm writing a SublimeText Plugin that uses a shelf for persistent storage of some data; the path of the shelf file is defined in the settings of the current project. I have a WindowCommand and a keybinding for it that initializes the class that holds the shelf, but I want to automatically execute this on startup if a suitable project is open.
Simply running the command when the plugin is loaded fails because sublime.active_window() is still uninitialized - my current workaround is to use set_timeout with a (hopefully) large enough timeout:
import sublime, sublime_plugin
_data = None
class MkshelfCommand(sublime_plugin.WindowCommand):
def run(self):
global _data
shelf_path = self.window.active_view().settings().get("shelf_path")
if shelf_path:
_data = MyClass(shelf_path)
sublime.set_timeout(lambda: sublime.active_window().run_command("mkshelf"), 1000)
This is obviously all kinds of bad; but I couldn't figure out how to do this more reliably as I could neither find a way to access the current projects settings without a view, nor a method to ensure the window exists before executing the command so I could get rid of the timeout (I've thought of abusing EventListener.on_activated, but this seems even more ugly than what I'm doing right now). Is there a better way to do this or should I just bite the bullet and stick with my current approach?
Instead of calling sublime.active_window() directly in you timeout callback, call a function that calls itself when active_window() is still None:
def runCommandWhenInitialized():
activeWindow = sublime.active_window()
if activeWindow is not None:
activeWindow.run_command("mkshelf")
else:
sublime.set_timeout(lambda: runCommandWhenInitialized(), 100)
sublime.set_timeout(lambda: runCommandWhenInitialized(), 100)
(I didn't actually run this code, but I think it should work.)
Try defining a module level method called plugin_loaded. It might
only work in Sublime 3. I don't know which one you're using.
def plugin_loaded():
pass
http://www.sublimetext.com/docs/3/api_reference.html

python curses addstr error - but only on my computer

I was writing a little program that takes a list and generates a menu out of it in curses (straight up, standard library or whatever, batteries included python's curses) when I noticed the strangest problem (if you'd like, a heavily commented copy of the entire program is below). Simply put, when accepting the results of an os.listdir generated list, curses crashes with an addstr ERR, BUT, if I feed it a hardcoded list, it works fine. This, of course, makes absolutely no sense, right? A list is a list is a list and a list by any other name should still be a list, right?
To make things even more complicated, I sent the code to a friend of mine who works mainly in python2.6 (mine was originally written to work in python3.1). He uncommented the broken_input() call (which feeds the program the os.listdir generated information) and said that it worked fine for him. I have both python 2.6 and 3.1 installed, so I changed my shebang to make the program run in 2.6, and (with the broken_input() uncommented) for me, it still throws the addstr ERR (yet runs fine with the hardcoded input... which is, of course, btw, entirely useless apart from proof of concept).
Thus, my question is this: is there something broken in my python installation (I'm running Ubuntu lucid, with python2.6.5 and 3.1 installed), and, if so, how do I fix it so I can get curses to execute this code properly. And, if it's not my python installation, how can I get the same functionality out of curses (i.e.: paint a menu from a list containing an arbitrary number of items, numbering them so that the user can make a selection based on the item number).
#!/usr/bin/env python3.1
"""curses_mp3eater.py: a curses-based implementation of my mp3eater program;
diplays the contents of cwd, allows user to make a selection. But I'm having
problems getting it to iterate over a list.
v0.1 03.14.11
by skookie sprite
address#gmail.com
"""
import curses, curses.wrapper, os, sys
def working_input():
"""the following is demo code to demonstrate my problem... main will accept the following,
but won't accept the product of a directorylist for reasons that I can't figure out."""
dircontents=['this','is','a','list','','and','it','will','iterate','fine','in','the','(main) function.']
return dircontents
def broken_input():
"""this is the code that I NEED to have work... but for reasons beyond me will not iterate in
the main function. It's a simple list of the contents of the CWD."""
cwd=os.getcwd()
dircontents=[]
for item in os.listdir(cwd):
dircontents += [item]
return dircontents
def main(stdscr):
"""This is the program. Designed to take a list of stuff and display it. If I can solve
that hurdle, I'll add selection mechanisms, and break it across screens - amongst other
things. But, currently, it can only accept the demo code. Uncomment one or the other to
see what I mean."""
#broken_input returns an addstr() ERR, but I don't see the difference between working_input
#and broken_input as they are both just lists.
#working_input() is demo code that illustrates my problem
stuffin=working_input()
#stuffin=broken_input()
#the rest of this stuff works. The problem is with the input. Why?
linenumber=int()
linenumber=6
itemnumber=int()
itemnumber=1
stdscr.clear()
stdscr.border(0)
for item in stuffin:
stdscr.addstr(linenumber, 10, '%s - %s' % (itemnumber, item), curses.A_NORMAL)
linenumber += 1
itemnumber += 1
curses.doupdate()
stdscr.getch()
if __name__ == '__main__':
curses.wrapper(main)
You're stuffing too much onto the screen and thus passing an out-of-bounds line number to addstr. If you make an empty directory to run the program in (or enlarge your terminal window), it works.
To fix this, check the number of lines in the window before the output loop in main.
use screen.scrollok(1) after addstr to allow the text to scroll.
The problem is explained in the addch manual page:
The addch, waddch, mvaddch and mvwaddch routines put the character ch
into the given window at its current window position, which is then
advanced. They are analogous to putchar(3) in stdio(3). If the
advance is at the right margin:
The cursor automatically wraps to the beginning of the next line.
At the bottom of the current scrolling region, and if scrollok is
enabled, the scrolling region is scrolled up one line.
If scrollok is not enabled, writing a character at the lower right
margin succeeds. However, an error is returned because it is not
possible to wrap to a new line
The given program neither catches an error from the lower right margin (probably should say "corner"), nor calls scrollok to allow the data to scroll up. In the latter case, you will lose information which is scrolled up, while handling the exception would allow you to prompt after a screen's worth of data is displayed, and then either quit or display more data.

Can't figure out how to invoke cProfile inside of a program

Sorry for the beginner question, but I can't figure out cProfile (I'm really new to Python)
I can run it via my terminal with:
python -m cProfile myscript.py
But I need to run it on a webserver, so I'd like to put the command within the script it will look at. How would I do this? I've seen stuff using terms like __init__ and __main__ but I dont really understand what those are.
I know this is simple, I'm just still trying to learn everything and I know there's someone who will know this.
Thanks in advance! I appreciate it.
I think you've been seeing ideas like this:
if __name__ == "__main__":
# do something if this script is invoked
# as python scriptname. Otherwise, gets ignored.
What happens is when you call python on a script, that file has an attribute __name__ set to "__main__" if it is the file being directly called by the python executable. Otherwise, (if it is not directly called) it is imported.
Now, you can use this trick on your scripts if you need to, for example, assuming you have:
def somescriptfunc():
# does something
pass
if __name__ == "__main__":
# do something if this script is invoked
# as python scriptname. Otherwise, gets ignored.
import cProfile
cProfile.run('somescriptfunc()')
This changes your script. When imported, its member functions, classes etc can be used as normal. When run from the command-line, it profiles itself.
Is this what you're looking for?
From the comments I've gathered more is perhaps needed, so here goes:
If you're running a script from CGI changes are it is of the form:
# do some stuff to extract the parameters
# do something with the parameters
# return the response.
When I say abstract out, you can do this:
def do_something_with_parameters(param1, param2):
pass
if __name__ = "__main__":
import cProfile
cProfile.run('do_something_with_parameters(param1=\'sometestvalue\')')
Put that file on your python path. When run itself, it will profile the function you want profiling.
Now, for your CGI script, create a script that does:
import {insert name of script from above here}
# do something to determine parameter values
# do something with them *via the function*:
do_something_with_parameters(param1=..., param2=...)
# return something
So your cgi script just becomes a little wrapper for your function (which it is anyway) and your function is now self-testing.
You can then profile the function using made up values on your desktop, away from the production server.
There are probably neater ways to achieve this, but it would work.

Categories

Resources