Python3 Qt5 MainWindow - python-3.x

I have an application flow which looks like this. At startup a MainWindow is shown and asks the user to choose a project or create a new one. After a project is created or chosen from the list, I want to close this MainWindow and open another MainWindow.
In my main.py the code looks like this:
app = QApplication([])
ui_project_list_view = ProjectListView()
ui_project_list_view.show()
app.exec_()
Now I want to close the first main window (ui_project_list_view) and open the other main window (ui_project_view). This code is called from within ui_project_list_view.
ui_project_view = ProjectView()
ui_project_view.show()
main_view.close()
No matter in which order I show or close, the application quits. How should I design my "window-flow" ?
Thanks for your help.

If you open most programs like Word or Excel- or QtDesigner for example- you'll see a blank main window initialize, and then a popup will appear asking you to choose your project.
If you wanted to apply this to your code, the ProjectView should be the main window and the ProjectListView would be the popup. The ProjectView would call this after initializing, in a setup function perhaps. After ProjectListView finishes, then ProjectView would just need to update the screen with the information that ProjectListView has.

Related

Can I use tk.Tk() again if I destroy the previous instance?

I know that using multiple tk.Tk() in a single app is a bad practice and if I want to create multiple windows I should use tk.Toplevel() instead. But what if I destroy the previous tk.Tk() instance and then call other instance? Technically the first endless loop has ended, so I should be fine, right?
For example, I've written an application that starts off with login screen and then I move to, let's say, "mainwindow" and this is the screen the user will be watching the most often. Login screen is only a one-time thing when starting the app and user will not return to it again (unless he closes the "mainwindow" and runs the app again). Would it be more logical to call tk.Tk() on login window and after choosing "login" button destroy login window and then call "mainwindow" as tk.Tk()?
Technically, I could just withdraw the login window and create all windows as children of the login window using tk.Toplevel (and the flow would be loginwindow -> mainwindow -> otherwindows), but I wonder - is keeping windows whitdrawn when you won't need them again a good practice?
You can actually create as many windows as you want.
This code right here does perfectly work for me. You just create several objects from one class.
from tkinter import *
windows = []
for x in range(5):
windows.append(Tk())
Button(windows[-1], text='Destroy this window', command=windows[-1].destroy).pack()
windows[-1].mainloop()
So, you can destroy one window, then create another, or even make them work at the same time.

how do I identify if a popup comes up

I'm making a sneaker bot that simulates a checkout on shoe palace (using air force 1s as an example in this program). Basically what I'm having trouble with is after about 5 seconds after opening the website (it's not a consistent amount of time) I get a popup basically just advertising signing up for their club or whatever and it screws up my code because the button doesn't get pressed so the script terminates. I've tried using time.sleep(5) to hopefully wait for it to popup and then simulating pressing the escape key to close it but it just doesn't work. Is there a way that I can recognize when the popup comes up so I can run a piece of code that closes it immediately? Below I have the code I'm using currently which in an instance where the popup doesn't come up works perfectly. Any help is GREATLY appreciated as I've been stumped with this problem.
from selenium import webdriver
import time
# from pynput.keyboard import Key, Controller
# keyboard = Controller()
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
#driver.delete_all_cookies()
#open product page (CHANGE THIS)
#driver.get('https://www.shoepalace.com/product/nike/ck7214-100/air-force-1-07-lv8-2-mens-lifestyle-shoe-white-white/')
driver.get('https://www.shoepalace.com/product/nike/ck7214-100/air-force-1-07-lv8-2-mens-lifestyle-shoe-white-white/')
time.sleep(.025)
#secondary size
button = driver.find_element_by_xpath("/html/body/div[2]/div[4]/form/div[1]/button[5]")
button.click()
#primary size
button = driver.find_element_by_xpath("/html/body/div[2]/div[4]/form/div[1]/button[7]")
button.click()
#add to cart
button = driver.find_element_by_xpath("/html/body/div[2]/div[4]/form/div[2]/input")
button.click()
#checkout
button = driver.find_element_by_xpath("/html/body/div[2]/div/div[2]/div/div/div/ul[2]/li[1]")
button.click()
You can create a method where you should:
Identify if the pop-up is displayed
Close it if so
Wait until pop-up is not displayed
Keep in mind that your code runs line by line, so if you know when the pop up can appear, you can add your method there. If not, based on your code structure is a tricky one because you will need to add it before each action.

Programmatically changing tabs in a Monotouch app

Forgive me for my ignorance, as I'm new to Monotouch and I'm sure this is a simple thing but I can't find the answer anywhere.
I have an iPhone app in Monotouch that uses a UITabBarController for root navigation. It is defined in it's own class file. There is also a separate view controller class file for the content of each tab. So tab1 shows viewcontroller1, tab2 shows viewcontroller2, etc.
I want a user to be able to click on button1 inside of viewcontroller1 and have the app take them to tab2 and show viewcontroller2.
I have an event handled for the click of button1 and I can do things like pop up alerts when it's clicked, but I can't figure out how to get the tab bar to be accessible for me to call it. Please help!
Edit: I need to know not only how to make it accessible, but I also don't know what method to call to make it change.
When you create your "child" view controllers, pass in a reference to the "parent" tab controller. Then you child can call a method on it's parent to update the current tab index.
something like
btn1.TouchUpInside += (sender, args) => TabBarController.SelectedIndex = 0 ;

Getting pyqt application focus for popup menu to disappear when clicking away from it

Let me quickly explain the background to this. I'm developing a custom menu system inside a 3D application called Softimage XSI. It has a PyQt application object created already and ProcessEvents is being called a certain number of times every second so that PyQt applications can exist in a non-modal state within XSI.
To implement the menu, I've got a webpage embedded in a toolbar which is calling a plugin for XSI that I've written to show a PyQt menu. This all works fine (albeit, slightly contrived!).
The issue is that when I show the menu, it won't disappear when I click away from it. If I move the mouse over the menu, and then click away from it, it will disappear. It's only when it first pops up.
I've tried everything I can think of. Here's a list:
Using QtGui.qApp.installEventFilter(menu) to try and catch the mousepressed signal. It never gets triggered. I suspect the application itself isn't receiving the click.
Using menu.raise_() makes no difference
Neither does QtGui.qApp.setActiveWindow(menu)
Or menu.setFocus()
I've also tried:
event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, pos, QtCore.Qt.NoButton, QtCore.Qt.NoButton, QtCore.Qt.NoModifier)
QtGui.qApp.sendEvent(menu, event)
I had a go writing my own QEventLoop, but it just crashed XSI. I suspect trying to run a modal loop inside the other one probably isn't a legal thing to do. Either that, or I really don't know what I'm doing (equally probable)
The only thing I have partial success with is using grabMouse(). This is what makes the menu close if I click away from the menu (only after the mouse has passed over the menu once), but I have to call it a couple of times for it to "stick".
So this is my code at the moment:
class MyMenu (QtGui.QMenu):
def __init__(self, parent = None):
QtGui.QMenu.__init__(self, parent)
self.grabbed=2
def getMouse(self):
if self.grabbed>0:
self.grabMouse()
self.grabbed-=1
def paintEvent(self, event):
QtGui.QMenu.paintEvent(self, event)
self.getMouse()
def hideEvent(self, event):
self.releaseMouse()
def ShowMenu():
menu = MyMenu()
menu.addAction("A")
menu.addAction("B")
menu.addAction("C")
submenu = MyMenu()
submenu.addAction("D")
submenu.addAction("E")
submenu.addAction("F")
menu.addMenu(submenu)
menu.setTearOffEnabled(True)
menu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setTitle("Window")
submenu.setTearOffEnabled(True)
pos = QtGui.QCursor.pos()
pos.setX(105)
menu.popup(pos)
#Prevent garbage collection
QtGui.XSIMenu=menu
QtGui.XSISubMenu=submenu
#Desperate acts!
menu.raise_()
QtGui.qApp.setActiveWindow(menu)
menu.setFocus()
Any thoughts or random suggestions would be very gratefully received as this is driving me nuts! Don't be afraid to suggest modifications to stuff I've already tried, as I'm relatively new to PyQt and I may well have missed something.
Many thanks,
Andy
Just before calling popup with self.trayMenu.popup(QtGui.QCursor.pos()), call self.trayMenu.activateWindow(). Putting activateWindow before popup makes the left-click menu work the same as the right-click menu and it goes away when you click elsewhere. :)

How to change the function called when I click in the close button on php-gtk?

I load a single instance of a window on php-gtk, I have a button named "Cancel" that hide(); the window, so when the window is needed again I just show();.
But when I click on the close button instead of the cancel button the window is destroyed. Even when I redirect the event (I'm not sure if i'm doing it right) it calls the first(just hide() function) and then the destroy method.
Any idea?
PD: I wouldn't want to destroy and recreate the windows because of php's crappy garbage collector and to be able to maintain previous data without having to refill the whole window(after all is supposed to be a desktop app).
Following the advice here: delete-event.
I changed my code to return TRUE:
function on_multipleCancelButton_activate()
{
global $GladeMultiple;
$MultipleWindow = $GladeMultiple->get_widget('multipleWindow');
$MultipleWindow->hide();
return TRUE;
}
On the GTK designer I linked the delete-event to this function.

Resources