TortoiseHg hook with GUI - python

We are trying to write a mercurial pre-commit hook which should work with both commandline and TortoiseHg.
The idea of the hook is to connect to JIRA and get the list of activities assigned to the developer, and show the activities in a list from which the developer can choose one. The JIRA ID and summary will then be put in the commit comment.
Now, we have the basic parts of most of the functionality figured out, but are missing a way to show a list. We've tried to show a basic QtWidget with input field and a button (using PyQt4), and using the command line the window appears, we can enter text and press the button to print the text (or send it out with ui.status).
In TortoiseHg (version 2.7.1) it doesn't work that well. The hook fires and the window opens but it appears as if control is not properly passed on. The input field on the new window doesn't get active, we can't see when we type text, but when clicking the button the contents are printed to ui.status. More worringly is that TortoiseHg stops updating the graphics, so when the window is closed there is a blank spot in the TortoiseHg window and THG doesn't respond to any input. We have to use the process explorer to shoot it down.
Any hints as to how to write a hook which opens a window which we can interact with under TortoiseHg?
Hook definition:
pre-commit = python:e:\repos\SCM-TOOLS\hg-hooks\user.py:hook
Python code:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class AppForm(QMainWindow):
def __init__(self, ui, parent=None):
QMainWindow.__init__(self, parent)
self.u = ui
self.create_main_frame()
def create_main_frame(self):
page = QWidget()
self.button = QPushButton('Test', page)
self.edit1 = QLineEdit()
vbox1 = QVBoxLayout()
vbox1.addWidget(self.edit1)
vbox1.addWidget(self.button)
page.setLayout(vbox1)
self.setCentralWidget(page)
self.connect(self.button, SIGNAL("clicked()"), self.clicked)
def clicked(self):
self.u.status (str(self.edit1.text()))
def hook(ui, repo, **kwargs):
app = QApplication(sys.argv)
form = AppForm(ui)
form.show()
app.exec_()
sys.exit(1)
Edit:
In addition to this working in TortoiseHg and from the commandline it should also work in Eclipse and IntelliJ, therefore the suggested TortoiseHg plugins are not a full solution.

This task would normally be handled differently in Tortoise products as they already have a defined issue tracker plugin interface. This is defined here.
From the user point of view, they get a new button on the commit window which presents them with a list of issues to choose from. This then adds the appropriate text to the commit message.
There are two tortoise issue tracker plugins for Jira: 1, 2
I know that they say that they are TortoiseSvn plugins but they should work for TortoiseHg too - we use the TurtleMine one with no issues.

Related

Showing and hiding multiple windows in PyQt5

I'm working on a project with UI and I started to do it with PyQt5. So far I watched lots of videos read some tutorials and have progress on the project. Since PyQt is a binding of C++ for Python, there are not so many documents for complex UI with lots of windows.(or I couldn't find it and also looked examples of PyQt5). My project contains lots of windows. I'm trying to take some arguments from a user and due to user arguments optimization algorithm will work. So the project contain's these windows
Login Window(Qwidgets) {first view}
Login Sign up Window (Qwidgets) {if user don't have an account second view}
If user logs into system Tabwidget will be shown with 4 subtab view and these tabs will take arguments from a user. In this widget, there is already 2 subtab have already values that user can choose but also there are buttons which open new Qwidget class windows with OK and CANCEL button. One tab for choosing a file directory and I used QfileDialog class here. And last tab taking last arguments from a user and opening the file that user has chosen in 3rd tab.
After Tab view, I opened a Plotview, with the file that user have chosen, and in that window user by drawing some polygons giving argument on plot.{Im using Pyqtgraph library here}
Optimization Algorithm will work it's not connected with Pyqt
I have used Qt Designer mostly while designing UI. But later changed it adding some methods to take arguments from a user and for connecting other tabs or other windows.
By defining methods in the class (window) I can open other windows but I cant hide or close an already opened window. if I try to close them all process goes down but I want to make the only that window close. I have that problem in Login Signup window, popup windows for taking extra arguments from a user in 1st and 2nd tabview. My main starts with Login Window. After that in Loginwindow if login success it goes to tabview window. I have been successful by typing mainwindow.hide() and showing tabview window. But after that in all popup windows, I cant close the popup windows that takes arguments from a user.
Since the code is so long I will just put here interested parts.
class LoginUp(object):
def setupUi(self,LoginUp):
self.Buton1.clicked.connect(self.signup)
self.Buton2.clicked.connect(self.tabview)
def signup(self):
# here it shows but user cant close it by just clicking on OK button
# He must click on x button to close which I dont want.
self.signupshow = QtWidgets.QWidget()
self.ui = LoginSignUp()
self.ui.setupUi(self.signupshow)
self.signupshow.show()
def tabview(self): # Here its works
self.tabviewshow = QtWidgets.QWidget()
self.ui_tabview = TabView()
self.ui_tabview.setupUi(self.tabviewshow)
MainWindow.close()
self.tabviewshow.show()
class TabView(object):
def setupUi(self,Form):
self.button3.clicked.connect(self.addargument)
def addargument(self):
# same problem.. after that it popups window that user can give inputs but cant close the window AddArgument class
self.Add = QtWidgets.QWidget()
self.addargumentshow = AddArgument()
self.addargumentshow.setupUi(self.Add)
self.addargumentshow.show()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QWidget()
ui = LoginUp()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
One way to solve this is to use another class as a controller for all of the windows you want to show.
In each window you will send a signal when you want to switch windows and it is up to this controller class to decide how to handle the signal when received and decide which window to show. Any arguments that you need passed can be passed through the signals.
Here is a simplified complete working example.

Capture the "Save your changes" dialog when using win32gui and closing an embedded application within a QApplication?

I am embedding an application within a tab in a pyqt QApplication. When I close the tab this application is embedded in how do I allow it to display the "Save your changes" dialog?
I use this on tab_close:
win32gui.PostMessage(int(wdg.process._handle),win32con.WM_CLOSE,0,0)
When I do this though, I lose this dialog box, if the application would normally throw one up.
The code looks similar to this:
class MainWindow(QTabWidget):
def __init__(self, parent=None):
QTabWidget.__init__(self, parent)
self.setTabsClosable(1)
self.tabCloseRequested.connect(self.close_tab)
...
def close_tab(self,ind):
wdg = self.widget(ind)
win32gui.PostMessage(int(wdg.process._handle),win32con.WM_CLOSE,0,0)
self.removeTab(ind)
del wdg
...
This produces a UI like this (with Window's notepad.exe embedded). Clicking the "X" on the tab will close Notepad without prompting the user to save any input.
How can I close the tab and allow the embedded application to prompt a user to save their changes?
You are on a path that will only bring you pain and disillusions.
Notepad is only one of the few Windows applications that has its source code available for free.
Recompile it and modify it to fit your purposes.
You will find-out that there are also other popup dialogs that you may need to get rid of.
Now, if you really want to continue with automation for Windows you will probably need something like https://pywinauto.github.io which happens to have an example for notepad.exe.

Opening other application in single window using python

I am new to python and want to learn this from the basic.
I want to open two other application like notepad in a single window. I searched for any examples by using "tkinter". Any idea for implementing this using "tkinter".
PS: two tabs one in left and one in right so that one tab will be having notepad and other will have a media player (let say) and i should be able to close the single parent window for closing this child windows.
On Unix systems with X server the XEmbed protocol exists for such purpose, but it requires the child application to be specifically prepared for that (here's a related question).
On Windows this can be accomplished using the Win32 API. You have to get the handles of the parent and child windows and use the SetParent function.
Here's a proof of concept:
from tkinter import Tk
from win32gui import SetParent, FindWindow, SetWindowPos
import time
import subprocess
def attach_window(window_class, parent, x, y, width, height):
child = FindWindow(window_class, None)
SetParent(child, parent)
SetWindowPos(child, 0, x, y, width, height, 0)
def main():
root = Tk()
subprocess.Popen('C:\\Windows\\system32\\notepad.exe')
subprocess.Popen('C:\\Windows\\system32\\calc.exe')
# Give child processes enough time to launch
time.sleep(0.5)
# Get the HWND of the parent window
parent = int(root.frame(), 16)
attach_window('Notepad', parent, 0, 0, 400, 200)
attach_window('CalcFrame', parent, 0, 205, 420, 320)
root.geometry('500x500')
root.mainloop()
if __name__ == '__main__':
main()
Keep in mind that you have to install PyWin32 for this to work.
I don't think you will be able to do this easily. Notepad is using its own toolkit which, most probably, is not compatible with the one you are using.
If you want to open eg. an editor, look for a widget in the toolkit of your choice which does what you want (or nearly). Eg. if you want an editor, use the GtkTextView in GTK, or, if you want something that can do code editing, look at GtkSourceView, etc. Same goes for media applications.
The 'include' applications as part of a project works only to a certain point. You can eg, include text-mode applications in a terminal window, but graphical apps are much harder.
For what you need, you will have to use libraries like tkinter or pyqt. As you want to learn it from the basic, I would suggest you to pick a GUI library and start learning it. Eventually you will know how to get the result that you desire.

Make a window appear on top of another, block access to other windows until button clicked

Python 2.7, PyQt4.8.5
I want to have a main app window and then a second pop up window to display com port settings. This window should always be on top of the parent window until either the ok or the cancel button is clicked; closing the child window. (sort of like a required answer i.e. cant process until you choose the settings from the child window)
Is there a Python Qt command to do this?
Apologies if this has been asked/answered before, my search returned nothing useful.
You want a modal dialog. For example:
dialog = QInputDialog()
dialog.exec_()
You can either implement your own dialog widget (by subclassing QDialog) or use one of the several available.

Help Me: Loading Qt dialogs from python Scripts

im a novice into developing an application using backend as Python (2.5) and Qt(3) as front end GUI designer. I have 5 diffrent dialogs to implement the scripts. i just know to load the window (main window)
from qt import *
from dialogselectkernelfile import *
from formcopyextract import *
import sys
if __name__ == "__main__":
app = QApplication(sys.argv)
f = DialogSelectKernelFile()
f.show()
app.setMainWidget(f)
app.exec_loop()
main dialog opens on running. i have a set of back,Next,Cancel buttons pusing on each should open the next or previous dialogs. i use the pyuic compiler to source translation.how can i do this from python. please reply i`m running out of time.i dont know how to load another dialog from a signal of push button in another dialog. Help me pls
Thanks a Lot
Are you connecting the button click signals to handler functions?
If you are able to get one dialog to open, getting the other dialogs to open should be as simple as instantiating the new dialog and calling the .show() method in the first dialog's button handler.
Maybe you could upload your code somewhere so we can see more of it. What you have above doesn't really help much.
def displayNextForm(self):
self.close()
self.extr=FormMakeImage(self,"FormMakeImage",1,Qt.WStyle_DialogBorder)
self.extr.exec_loop()
def displayPrevForm(self):
from DialogSelectFile import *
self.close()
self.ext=DialogSelectKernelFile(self,"SelectKernel",1,Qt.WStyle_DialogBorder)
self.ext.exec_loop()
This did work smooth. I was able to implement the Next back feature. Possible warnings are occuring on Imports. but no problem on running.
Thanks all

Categories

Resources