How to close the xxxxx.exe terminal window without killing the xxxxx process? - emacs

How does this Emacs command (make-comint-in-buffer "Python" nil "python" nil "-i") or (make-comint-in-buffer "git" nil "C:/Program Files (x86)/Git/bin/sh.exe" nil "--login" "-i") manage to get the prompt in an Emacs buffer and get ride of it's, Python's/sh.exe's, interactive terminal without killing the Python process?
I tried to figure out by taking a shallow dive into make-comint-in-buffer's source code but bumped into processp, which is C compiled code, whose source I couldn't find.
The reason I am asking this question is to find an alternative answer to this question without using pythonw (their aint a mayapyw.exe to mayapy.exe for example).

Emacs uses the SHOWWINDOW flag to CreateProcess to control display of the console window associated with a subprocess.
The key code from create_child in w32proc.c is:
if (NILP (Vw32_start_process_show_window) && !is_gui_app)
start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
else
start.dwFlags = STARTF_USESTDHANDLES;
start.wShowWindow = SW_HIDE;
if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE, flags, env, dir, &start, &cp->procinfo))
{ ...
}

I can only guess how that Emacs command works, so can't really help you there... But however, I can provide you with a way to hide a window. That is possible by using the CTypes module and call the Windows-API to get the Window/Python-prompts ID/Hwin, and then hide that window.
This forces you to import/or include this piece of code in your script, and then call a function/do a little something in your script. Once your script is run, this should hide the prompt. See "main.py"-part for usage.
Window.py
from ctypes import *
user32 = windll.user32
BOOL = c_bool
INT = c_int
LONG = c_long
LPVOID = c_void_p
LPTSTR = c_wchar_p
HWND = LPVOID
LPARAM = LPVOID
GW_OWNER = 4
GWL_EXSTYLE = -20
WS_EX_TOOLWINDOW = 128
WS_EX_APPWINDOW = 262144
#------------------------------------------------------------------------
def GetWindowLong(hwnd, index):
user32.GetWindowLongW.argtypes = [HWND, INT]
return user32.GetWindowLongW(hwnd, index)
def GetWindow(hWnd, uCmd):
user32.GetParent.argtypes = [HWND, INT]
return user32.GetWindow(hWnd, uCmd)
def GetParent(hwnd):
user32.GetParent.argtypes = [HWND]
return user32.GetParent(hwnd)
def IsWindowVisible(hwnd):
user32.IsWindowVisible.argtypes = [HWND]
return user32.IsWindowVisible(hwnd)
def GetWindowTextLength(hwnd):
user32.GetWindowTextLengthW.argtypes = [HWND]
return user32.GetWindowTextLengthW(hwnd)
def GetWindowText(hwnd):
length = GetWindowTextLength(hwnd)
if not length: return False
buff = create_unicode_buffer(length + 1)
user32.GetWindowTextW.argtypes = [HWND, LPTSTR, INT]
res = user32.GetWindowTextW(hwnd, buff, length + 1)
if res: return buff.value
else: return False
def isRealWindow(hwnd):
""" Check if a given window is a real Windows application frame..
Returns a BOOL """
if not IsWindowVisible(hwnd):
return False
if GetParent(hwnd) != 0:
return False
hasNoOwner = GetWindow(hwnd, GW_OWNER) == 0
lExStyle = GetWindowLong(hwnd, GWL_EXSTYLE)
if (((lExStyle & WS_EX_TOOLWINDOW) == 0 and hasNoOwner)
or ((lExStyle & WS_EX_APPWINDOW != 0) and not hasNoOwner)):
if GetWindowText(hwnd):
return True
return False
class WindowEnumerator(object):
""" Window enumerator class. You can pass it's instances
as callback functions in window enumeration APIs. """
def __init__(self):
self.hwnd = []
def __call__(self, hwnd, lParam):
self.hwnd.append(hwnd)
return True
class __EnumWndProc(WindowEnumerator):
pass
def EnumWindows():
WNDENUMPROC = WINFUNCTYPE(BOOL,HWND,LPARAM)
_EnumWindows = user32.EnumWindows
_EnumWindows.argtypes = [WNDENUMPROC, LPARAM]
_EnumWindows.restype = BOOL
EnumFunc = __EnumWndProc()
lpEnumFunc = WNDENUMPROC(EnumFunc)
if not _EnumWindows(lpEnumFunc, None):
errcode = GetLastError()
if errcode not in (ERROR_NO_MORE_FILES, ERROR_SUCCESS):
raise WinError(errcode)
return EnumFunc.hwnd
def GetWindowByName(title):
window = []
hwnds = EnumWindows()
for hwnd in hwnds:
if not isRealWindow(hwnd):
pass
else:
wndtitle = GetWindowText(hwnd)
if title.lower() in wndtitle.lower():
return (hwnd, wndtitle)
return False
def ShowWindow(hWnd, arg=0):
user32.ShowWindow.argtypes = [HWND, c_int]
return user32.ShowWindow(hWnd, arg)
main.py
import Window
# Pass the full or partial title of the window that should be hidden.
wnd = Window.GetWindowByName('xxxxxxx.exe')
if wnd:
Window.ShowWindow(wnd[0], 0) #Hide it. 0=SW_HIDE, 5 = SW_SHOW.
I hope this does the trick.

Related

Shake wx.Dialog after validation fails

I have a wx.Dialog with a custom validation process that runs after the OK button is pressed. If the validation fails I would like to shake the wx.Dialog to let users know that something is wrong with the given input.
Is there something like this implemented in wxPython?
The simplest way, would be activate a wx.Timer with a short interval that moves the dialog's position, when the processing fails.
Something like this:
import wx
class Busy(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self, parent, wx.ID_ANY, "Busy", size= (420,240))
self.panel = wx.Panel(self,wx.ID_ANY)
self.label = wx.StaticText(self.panel, label="Processing..................", pos=(120,20))
self.gauge = wx.Gauge(self.panel,size=(300,25),pos=(80,80))
self.livelabel = wx.StaticText(self.panel, label="Time to live:", pos=(80,110))
self.lltime = wx.StaticText(self.panel, label="10", pos=(160,110))
self.closeButton =wx.Button(self.panel, label="Cancel", pos=(180,160))
self.closeButton.Bind(wx.EVT_BUTTON, self.OnQuit)
self.Bind(wx.EVT_CLOSE, self.OnQuit)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.lifetimer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnLifeTimer, self.lifetimer)
self.lifetimer.Start(1000)
self.life = 10
self.Show()
self.alt_pos = False
def OnTimer(self, event):
curr_pos_x, curr_pos_y = self.GetPosition()
if self.alt_pos:
self.Move(curr_pos_x+2, curr_pos_y)
self.alt_pos = False
else:
self.Move(curr_pos_x+-2, curr_pos_y)
self.alt_pos = True
def OnLifeTimer(self, evt): #Update time to live
self.gauge.Pulse()
self.life -= 1
self.lltime.SetLabelText(str(self.life))
if self.timer.IsRunning() or self.life > 0:
return
else:
self.label.SetLabel("Timed Out")
self.timer.Start(50)
def OnQuit(self, event):
self.timer.Stop()
self.lifetimer.Stop()
self.result_text = None
self.EndModal(False)
app = wx.App()
dlg = Busy(parent = None)
result = dlg.ShowModal()
print (result)
if result:
print (dlg.result_text)
else:
print ("Dialog Cancelled")
dlg.Destroy()

How to use timer.performWithDelay with a method call

I'm using a Lua class to create two objects, each of which must check where the other is to determine their movement. I'm attempting to use timer.performWithDelay to have them check every second, but for some reason when I try to do this, the line
o.moveCheckTimer = timer.performWithDelay(1000, o:moveCheck, 0)
in the class constructor throws an error stating that "Function arguments are expected near ','".
I have attempted to use an anonymous function like this:
o.moveCheckTimer = timer.performWithDelay(1000, function() o:moveCheck() end, 0)
but that causes the timer of both objects to only call the function for the most recent object that was created and not for itself (also very confusing behavior, and if anyone knows why this happens I would love to learn why).
I have dug through the API and info on method calls thoroughly, but I can't seem to find anything that uses them both together, and I feel like I'm missing something.
How can I use the method call as the listener for this timer?
Here is the full constructor:
Melee = {}
Melee.__index = Melee
function Melee:new(id, name, lane, side)
local o = {}
setmetatable(o, Melee)
o.id = id
o.name = name
o.lane = lane
o.side = side
if name == "spearman" then
o.maxhp = 100
o.range = 1
o.damage = {10, 20}
o.imageName = "images/rebels/spearman.png"
else
error("Attempted to create melee unit with undefined name")
end
o.hp = o.maxhp
--Display self
o.image = display.newImageRect(mainGroup, "images/rebels/spearman.png", 80, 80)
o.image.x = 0
o.image.y = lanes[lane]
o.image.anchorY = 1
if side == 2 then
o.image.xScale = -1
o.image:setFillColor(0.8)
o.image.x = display.contentWidth - 100
end
--Move and attack
local destination = display.contentWidth
if side == 2 then
destination = 0
end
o.moving = 1
o.movement = transition.to(o.image, {x = destination, time = 30000+math.random(-200,200)})
o.moveCheckTimer = timer.performWithDelay(1000, o:moveCheck, 0)
--o.attackTimer = timer.performWithDelay(1000, self:attack, 0)
return o
end

Efficient way to optimise a Scala code to read large file that doesn't fit in memory

Problem Statement Below,
We have a large log file which stores user interactions with an application. The entries in the log file follow the following schema: {userId, timestamp, actionType} where actionType is one of two possible values: [open, close]
Constraints:
The log file is too big to fit in memory on one machine. Also assume that the aggregated data doesn’t fit into memory.
Code has to be able to run on a single machine.
Should not use an out-of-the box implementation of mapreduce or 3rd party database; don’t assume we have a Hadoop or Spark or other distributed computing framework.
There can be multiple entries of each actionType for each user, and there might be missing entries in the log file. So a user might be missing a close record between two open records or vice versa.
Timestamps will come in strictly ascending order.
For this problem, we need to implement a class/classes that computes the average time spent by each user between open and close. Keep in mind that there are missing entries for some users, so we will have to make a choice about how to handle these entries when making our calculations. Code should follow a consistent policy with regards to how we make that choice.
The desired output for the solution should be [{userId, timeSpent},….] for all the users in the log file.
Sample log file (comma-separated, text file)
1,1435456566,open
2,1435457643,open
3,1435458912,open
1,1435459567,close
4,1435460345,open
1,1435461234,open
2,1435462567,close
1,1435463456,open
3,1435464398,close
4,1435465122,close
1,1435466775,close
Approach
Below is the code I've written in Python & Scala, which seems to be not efficient and upto the expectations of the scenario given, I'd like to feedback from community of developers in this forum how better we could optimise this code as per given scenario.
Scala implementation
import java.io.FileInputStream
import java.util.{Scanner, Map, LinkedList}
import java.lang.Long
import scala.collection.mutable
object UserMetrics extends App {
if (args.length == 0) {
println("Please provide input data file name for processing")
}
val userMetrics = new UserMetrics()
userMetrics.readInputFile(args(0),if (args.length == 1) 600000 else args(1).toInt)
}
case class UserInfo(userId: Integer, prevTimeStamp: Long, prevStatus: String, timeSpent: Long, occurence: Integer)
class UserMetrics {
val usermap = mutable.Map[Integer, LinkedList[UserInfo]]()
def readInputFile(stArr:String, timeOut: Int) {
var inputStream: FileInputStream = null
var sc: Scanner = null
try {
inputStream = new FileInputStream(stArr);
sc = new Scanner(inputStream, "UTF-8");
while (sc.hasNextLine()) {
val line: String = sc.nextLine();
processInput(line, timeOut)
}
for ((key: Integer, userLs: LinkedList[UserInfo]) <- usermap) {
val userInfo:UserInfo = userLs.get(0)
val timespent = if (userInfo.occurence>0) userInfo.timeSpent/userInfo.occurence else 0
println("{" + key +","+timespent + "}")
}
if (sc.ioException() != null) {
throw sc.ioException();
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (sc != null) {
sc.close();
}
}
}
def processInput(line: String, timeOut: Int) {
val strSp = line.split(",")
val userId: Integer = Integer.parseInt(strSp(0))
val curTimeStamp = Long.parseLong(strSp(1))
val status = strSp(2)
val uInfo: UserInfo = UserInfo(userId, curTimeStamp, status, 0, 0)
val emptyUserInfo: LinkedList[UserInfo] = new LinkedList[UserInfo]()
val lsUserInfo: LinkedList[UserInfo] = usermap.getOrElse(userId, emptyUserInfo)
if (lsUserInfo != null && lsUserInfo.size() > 0) {
val lastUserInfo: UserInfo = lsUserInfo.get(lsUserInfo.size() - 1)
val prevTimeStamp: Long = lastUserInfo.prevTimeStamp
val prevStatus: String = lastUserInfo.prevStatus
if (prevStatus.equals("open")) {
if (status.equals(lastUserInfo.prevStatus)) {
val timeSelector = if ((curTimeStamp - prevTimeStamp) > timeOut) timeOut else curTimeStamp - prevTimeStamp
val timeDiff = lastUserInfo.timeSpent + timeSelector
lsUserInfo.remove()
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, timeDiff, lastUserInfo.occurence + 1))
} else if(!status.equals(lastUserInfo.prevStatus)){
val timeDiff = lastUserInfo.timeSpent + curTimeStamp - prevTimeStamp
lsUserInfo.remove()
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, timeDiff, lastUserInfo.occurence + 1))
}
} else if(prevStatus.equals("close")) {
if (status.equals(lastUserInfo.prevStatus)) {
lsUserInfo.remove()
val timeSelector = if ((curTimeStamp - prevTimeStamp) > timeOut) timeOut else curTimeStamp - prevTimeStamp
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, lastUserInfo.timeSpent + timeSelector, lastUserInfo.occurence+1))
}else if(!status.equals(lastUserInfo.prevStatus))
{
lsUserInfo.remove()
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, lastUserInfo.timeSpent, lastUserInfo.occurence))
}
}
}else if(lsUserInfo.size()==0){
lsUserInfo.add(uInfo)
}
usermap.put(userId, lsUserInfo)
}
}
Python Implementation
import sys
def fileBlockStream(fp, number_of_blocks, block):
#A generator that splits a file into blocks and iterates over the lines of one of the blocks.
assert 0 <= block and block < number_of_blocks #Assertions to validate number of blocks given
assert 0 < number_of_blocks
fp.seek(0,2) #seek to end of file to compute block size
file_size = fp.tell()
ini = file_size * block / number_of_blocks #compute start & end point of file block
end = file_size * (1 + block) / number_of_blocks
if ini <= 0:
fp.seek(0)
else:
fp.seek(ini-1)
fp.readline()
while fp.tell() < end:
yield fp.readline() #iterate over lines of the particular chunk or block
def computeResultDS(chunk,avgTimeSpentDict,defaultTimeOut):
countPos,totTmPos,openTmPos,closeTmPos,nextEventPos = 0,1,2,3,4
for rows in chunk.splitlines():
if len(rows.split(",")) != 3:
continue
userKeyID = rows.split(",")[0]
try:
curTimeStamp = int(rows.split(",")[1])
except ValueError:
print("Invalid Timestamp for ID:" + str(userKeyID))
continue
curEvent = rows.split(",")[2]
if userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==1 and curEvent == "close":
#Check if already existing userID with expected Close event 0 - Open; 1 - Close
#Array value within dictionary stores [No. of pair events, total time spent (Close tm-Open tm), Last Open Tm, Last Close Tm, Next expected Event]
curTotalTime = curTimeStamp - avgTimeSpentDict[userKeyID][openTmPos]
totalTime = curTotalTime + avgTimeSpentDict[userKeyID][totTmPos]
eventCount = avgTimeSpentDict[userKeyID][countPos] + 1
avgTimeSpentDict[userKeyID][countPos] = eventCount
avgTimeSpentDict[userKeyID][totTmPos] = totalTime
avgTimeSpentDict[userKeyID][closeTmPos] = curTimeStamp
avgTimeSpentDict[userKeyID][nextEventPos] = 0 #Change next expected event to Open
elif userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==0 and curEvent == "open":
avgTimeSpentDict[userKeyID][openTmPos] = curTimeStamp
avgTimeSpentDict[userKeyID][nextEventPos] = 1 #Change next expected event to Close
elif userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==1 and curEvent == "open":
curTotalTime,closeTime = missingHandler(defaultTimeOut,avgTimeSpentDict[userKeyID][openTmPos],curTimeStamp)
totalTime = curTotalTime + avgTimeSpentDict[userKeyID][totTmPos]
avgTimeSpentDict[userKeyID][totTmPos]=totalTime
avgTimeSpentDict[userKeyID][closeTmPos]=closeTime
avgTimeSpentDict[userKeyID][openTmPos]=curTimeStamp
eventCount = avgTimeSpentDict[userKeyID][countPos] + 1
avgTimeSpentDict[userKeyID][countPos] = eventCount
elif userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==0 and curEvent == "close":
curTotalTime,openTime = missingHandler(defaultTimeOut,avgTimeSpentDict[userKeyID][closeTmPos],curTimeStamp)
totalTime = curTotalTime + avgTimeSpentDict[userKeyID][totTmPos]
avgTimeSpentDict[userKeyID][totTmPos]=totalTime
avgTimeSpentDict[userKeyID][openTmPos]=openTime
eventCount = avgTimeSpentDict[userKeyID][countPos] + 1
avgTimeSpentDict[userKeyID][countPos] = eventCount
elif curEvent == "open":
#Initialize userid with Open event
avgTimeSpentDict[userKeyID] = [0,0,curTimeStamp,0,1]
elif curEvent == "close":
#Initialize userid with missing handler function since there is no Open event for this User
totaltime,OpenTime = missingHandler(defaultTimeOut,0,curTimeStamp)
avgTimeSpentDict[userKeyID] = [1,totaltime,OpenTime,curTimeStamp,0]
def missingHandler(defaultTimeOut,curTimeVal,lastTimeVal):
if lastTimeVal - curTimeVal > defaultTimeOut:
return defaultTimeOut,curTimeVal
else:
return lastTimeVal - curTimeVal,curTimeVal
def computeAvg(avgTimeSpentDict,defaultTimeOut):
resDict = {}
for k,v in avgTimeSpentDict.iteritems():
if v[0] == 0:
resDict[k] = 0
else:
resDict[k] = v[1]/v[0]
return resDict
if __name__ == "__main__":
avgTimeSpentDict = {}
if len(sys.argv) < 2:
print("Please provide input data file name for processing")
sys.exit(1)
fileObj = open(sys.argv[1])
number_of_chunks = 4 if len(sys.argv) < 3 else int(sys.argv[2])
defaultTimeOut = 60000 if len(sys.argv) < 4 else int(sys.argv[3])
for chunk_number in range(number_of_chunks):
for chunk in fileBlockStream(fileObj, number_of_chunks, chunk_number):
computeResultDS(chunk, avgTimeSpentDict, defaultTimeOut)
print (computeAvg(avgTimeSpentDict,defaultTimeOut))
avgTimeSpentDict.clear() #Nullify dictionary
fileObj.close #Close the file object
Both program above gives desired output, but efficiency is what matters for this particular scenario. Let me know if you've anything better or any suggestions on existing implementation.
Thanks in Advance!!
What you are after is iterator usage. I'm not going to re-write your code, but the trick here is likely to be using an iterator. Fortunately Scala provides decent out of the box tooling for the job.
import scala.io.Source
object ReadBigFiles {
def read(fileName: String): Unit = {
val lines: Iterator[String] = Source.fromFile(fileName).getLines
// now you get iterator semantics for the file line traversal
// that means you can only go through the lines once, but you don't incur a penalty on heap usage
}
}
For your use case, you seem to require a lastUser, so you're dealing with groups of 2 entries. I think you you have two choices, either go for iterator.sliding(2), which will produce iterators for every pair, or simply add recursion to the mix using options.
def navigate(source: Iterator[String], last: Option[User]): ResultType = {
if (source.hasNext) {
val current = source.next()
last match {
case Some(existing) => // compare with previous user etc
case None => navigate(source, Some(current))
}
} else {
// exit recursion, return result
}
}
You can avoid all the code you've written to read the file and so on. If you need to count occurrences, simply build a Map inside your recursion, and increment the occurrences at every step based on your business logic.
from queue import LifoQueue, Queue
def averageTime() -> float:
logs = {}
records = Queue()
with open("log.txt") as fp:
lines = fp.readlines()
for line in lines:
if line[0] not in logs:
logs[line[0]] = LifoQueue()
logs[line[0]].put((line[1], line[2]))
else:
logs[line[0]].put((line[1], line[2]))
for k in logs:
somme = 0
count = 0
while not logs[k].empty():
l = logs[k].get()
somme = (somme + l[0]) if l[1] == "open" else (somme - l[0])
count = count + 1
records.put([k, somme, count//2])
while not records.empty():
record = records.get()
print(f"UserId={record[0]} Avg={record[1]/record[2]}")

Specify Variable Initialization Order in Scala

I have a special class Model that needs to have its methods called in a very specific order.
I tried doing something like this:
val model = new Model
new MyWrappingClass {
val first = model.firstMethod()
val second = model.secondMethod()
val third = model.thirdMethod()
}
The methods should be called in the order listed, however I am seeing an apparently random order.
Is there any way to get the variable initialization methods to be called in a particular order?
I doubt your methods are called in the wrong order. But to be sure, you can try something like this:
val (first, second, third) = (
model.firstMethod(),
model.secondMethod(),
model.thirdMethod()
)
You likely have some other problem with your code.
I can run 100 million loops where it never gets the order wrong, as follows:
class Model {
var done = Array(false,false,false);
def firstMethod():Boolean = { done(0) = true; done(1) || done(2) };
def secondMethod():Boolean = { done(1) = true; !done(0) || done(2) };
def thirdMethod():Boolean = { done(2) = true; !done(0) || !done(1) };
};
Notice that these methods return a True if done out of order and false when called in order.
Here's your class:
class MyWrappingClass {
val model = new Model;
val first = model.firstMethod()
val second = model.secondMethod()
val third = model.thirdMethod()
};
Our function to check for bad behavior on each trial:
def isNaughty(w: MyWrappingClass):Boolean = { w.first || w.second || w.third };
A short program to test:
var i = 0
var b = false;
while( (i<100000000) && !b ){
b = isNaughty(new MyWrappingClass);
i += 1;
}
if (b){
println("out-of-order behavior occurred");
println(i);
} else {
println("looks good");
}
Scala 2.11.7 on OpenJDK8 / Ubuntu 15.04
Of course this doesn't prove it impossible to have wrong order, only that correct behavior seems highly repeatable in a fairly simple case.

Python/Gtk3 : How to add a Gtk.Entry to a Gtk.MessageDialog?

Good morning,
I'm trying to add a Gtk.Entry to a Gtk.MessageDialog. With the following code it seems that I added the Gtk.Entry but it's not visible on the dialog window (Python3/Gtk3):
#!/usr/bin/python3
from gi.repository import Gtk
def get_user_pw(parent, message, default=''):
dialogWindow = Gtk.MessageDialog(parent,
Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
Gtk.MessageType.QUESTION,
Gtk.ButtonsType.OK_CANCEL,
message)
dialogBox = dialogWindow.get_content_area()
userEntry = Gtk.Entry()
userEntry.set_visibility(False)
userEntry.set_invisible_char("*")
userEntry.set_size_request(250,0)
userEntry.set_text("Test")
dialogBox.pack_end(userEntry, False, False, 0)
#dialogWindow.vbox.pack_start(userEntry, False, False, 0)
response = dialogWindow.run()
text = userEntry.get_text()
dialogWindow.destroy()
if response == Gtk.ResponseType.OK:
return text
else:
return None
class MainWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="MyWindowTitle")
userPassphrase = get_user_pw(self, "SSH key passphrase")
print("User passphrase: " + userPassphrase)
This code prints :
User passphrase: Test
I'm looking for clues about making the entry visible and editable, any help is welcome.
References:
http://python-gtk-3-tutorial.readthedocs.org/en/latest/dialogs.html
http://developer.gnome.org/gtk3/3.2/GtkDialog.html
Simple, versatile and re-usable entry dialog (sometimes referred to as input dialog) in PyGTK
Ok it works now, I needed to show_all() before run(). It took me some times to figure out this simple thing. Debugged code is :
def get_user_pw(parent, message, title=''):
# Returns user input as a string or None
# If user does not input text it returns None, NOT AN EMPTY STRING.
dialogWindow = Gtk.MessageDialog(parent,
Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
Gtk.MessageType.QUESTION,
Gtk.ButtonsType.OK_CANCEL,
message)
dialogWindow.set_title(title)
dialogBox = dialogWindow.get_content_area()
userEntry = Gtk.Entry()
userEntry.set_visibility(False)
userEntry.set_invisible_char("*")
userEntry.set_size_request(250,0)
dialogBox.pack_end(userEntry, False, False, 0)
dialogWindow.show_all()
response = dialogWindow.run()
text = userEntry.get_text()
dialogWindow.destroy()
if (response == Gtk.ResponseType.OK) and (text != ''):
return text
else:
return None
I use it like this :
class MainWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="MyWindowTitle")
userPassword = get_user_pw(self, "Please enter your password", "Password")
This may be going about it the hard way if this is just to run a sudo command - you could simply call
os.system('pkexec (yourcommand)')