Community,
i'm a complete noob in programming but i've learned quite a lot from stackoverflow (i hope...)
my question:
i'm working with ironpython and trying to create a GUI. Currently i'm struggling to get the KeyPress Event to work. I have TextBox and if someone presses the "Enter Key" it should do something. Like starting another function.
I'm using the IDE PyCharm to code.
I appreciate your help with this question. Thanks in advance :)
Here is what i've tried so far (just an example, not the real code):
import clr
# Set references
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")
# Import Winforms
from System.Drawing import *
from System.Windows.Forms import *
class MyClass(Form):
def __init__(self):
self.Text = "MyGui"
self.Size = Size(500, 500)
self.CenterToScreen()
self.create_textbox()
def create_textbox(self):
mytxtbox = TextBox()
mytxtbox.Name = "Textbox1"
mytxtbox.Location = Point(50, 50)
mytxtbox.Size = Size(100, 25)
mytxtbox.KeyPress += KeyPressEventHandler(self.press)
def press(self, sender, args):
key = args.KeyChar
if key == Keys.Enter:
print("You pressed Enter in the TextBox")
# Run this thang
form1 = MyClass()
Application.Run(form1)
You want to use KeyDown to get Enter key, instead of KeyPress:
mytxtbox.KeyDown += on_enter
def on_enter(self, e, args):
key = e.KeyChar
if key == Keys.Enter:
print("You pressed Enter in the TextBox")
Related
I am using Flink 1.12 and I have a keyed stream, in my code it looks that both A and B share the same watermark? and therefore B is determined as late because A's coming has upgraded the watermark to be 2020-08-30 10:50:11?
The output is A(2020-08-30 10:50:08, 2020-08-30 10:50:16):2020-08-30 10:50:15,there is no output for B
I would ask whether it is possible to make different keys have independent watermark? A's watermark and B'watermark change independently
The application code is:
import java.text.SimpleDateFormat
import java.util.Date
import java.util.concurrent.TimeUnit
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks
import org.apache.flink.streaming.api.scala.function.WindowFunction
import org.apache.flink.streaming.api.scala.{StreamExecutionEnvironment, _}
import org.apache.flink.streaming.api.watermark.Watermark
import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow
import org.apache.flink.util.Collector
object DemoDiscardLateEvent4_KeyStream {
def to_milli(str: String) =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(str).getTime
def to_char(milli: Long) = {
val date = if (milli <= 0) new Date(0) else new Date(milli)
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)
}
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
val data = Seq(
("A", "2020-08-30 10:50:15"),
("B", "2020-08-30 10:50:07")
)
env.fromCollection(data).setParallelism(1).assignTimestampsAndWatermarks(new AssignerWithPunctuatedWatermarks[(String, String)]() {
var maxSeen = Long.MinValue
override def checkAndGetNextWatermark(lastElement: (String, String), extractedTimestamp: Long): Watermark = {
val eventTime = to_milli(lastElement._2)
if (eventTime > maxSeen) {
maxSeen = eventTime
}
//Allow 4 seconds late
new Watermark(maxSeen - 4000)
}
override def extractTimestamp(element: (String, String), previousElementTimestamp: Long): Long = to_milli(element._2)
}).keyBy(_._1).window(TumblingEventTimeWindows.of(Time.of(8, TimeUnit.SECONDS))).apply(new WindowFunction[(String, String), String, String, TimeWindow] {
override def apply(key: String, window: TimeWindow, input: Iterable[(String, String)], out: Collector[String]): Unit = {
val start = to_char(window.getStart)
val end = to_char(window.getEnd)
val sb = new StringBuilder
//the start and end of the window
sb.append(s"$key($start, $end):")
//The content of the window
input.foreach {
e => sb.append(e._2 + ",")
}
out.collect(sb.toString().substring(0, sb.length - 1))
}
}).print()
env.execute()
}
}
While it would sometimes be helpful if Flink offered per-key watermarking, it does not.
Each parallel instance of your WatermarkStrategy (or in this case, of your AssignerWithPunctuatedWatermarks) is generating watermarks independently, based on the timestamps of the events it observes (regardless of their keys).
One way to work around the lack of this feature is to not use watermarks at all. For example, if you would be using per-key watermarks to trigger keyed event-time windows, you can instead implement your own windows using a KeyedProcessFunction, and instead of using watermarks to trigger event time timers, keep track of the largest timestamp seen so far for each key, and whenever updating that value, determine if you now want to close one or more windows for that key.
See one of the Flink training lessons for an example of how to implement keyed tumbling windows with a KeyedProcessFunction. This example depends on watermarks but should help you get started.
I am trying to implement programmatically selected (using regex) text formatting in a WPF RichTextBox. The use case is simply a WPF RichTextBox in which the user types text. However, to improve or accelerate readability i want to incorporate some automatic formatting as the text is typed.
The following code from How to select text from the RichTextBox and then color it? is exactly what i am trying to do. However, as far as i can tell this code is for a WinForms RichTextBox:
public void ColourRrbText(RichTextBox rtb)
{
Regex regExp = new Regex(#"\b(For|Next|If|Then)\b");
foreach (Match match in regExp.Matches(rtb.Text))
{
rtb.Select(match.Index, match.Length);
rtb.SelectionColor = Color.Blue;
}
}
I have tried to convert it as follows:
public static void ColorSpecificText(RichTextBox rtb)
{
TextRange textRange = new TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd);
Regex regex = new Regex(#"\b(For|Next|If|Then)\b");
foreach (Match match in regex.Matches(textRange.Text))
{
textRange.Select(match.Index, match.Length); // <--- DOESN'T WORK
textRange.SelectionColor = Color.Blue; // <--- DOESN'T WORK
}
}
However, i am stuck on how to convert the "match.Index, match.Length" and the "SelectionColor" syntax to something that the WPF RichTextBox knows how to handle. I have searched other posts, but most also seem to be for WinForms RichTextBox, not WPF. Any guidance would be greatly appreciated.
This is the syntax:
TextRange textRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
textRange.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Black);
Regex regex = new Regex(#"\b(For|Next|If|Then)\b");
int i = 0;
foreach (Match match in regex.Matches(textRange.Text))
{
var wordStartOffset = textRange.Start.GetPositionAtOffset(i + match.Index);
var wordEndOffset = textRange.Start.GetPositionAtOffset(i + match.Index + match.Length);
var wordRange = new TextRange(wordStartOffset, wordEndOffset);
wordRange.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.LightBlue);
i += 4; // could be something else
}
Although it may not highlight correctly because of your strategy. I'm afraid string index is not enough to create the proper TextPointer. +4 is used to skip formatting overheads, that's why it may not work if other formattings are present.
I developed an IronPython-wpf application with GUI using XAML. The user enter all the inputs in the GUI and I can save them. My problem is how I could pass those variables to my main python code after USER closes the GUI? To close the GUI, I have a button, which closes the GUI, If the USER click it.
What I did is as follows (I just copied some portion of the code):
import wpf
class MyApp(Window):
def __init__(self):
self.opencfgfile()
self.ictemp = self.FindName('pipent')
self.ictemp.Text = self.ictest
self.button = self.FindName('button')
self.button.Click += self.onClick
def onClick(self, sender, event):
self.Close()
def opencfgfile(self):
sstest = os.environ['test']
infile = open (sstest + '\config\test_Config.cfg' , 'r')
for line in infile:
if line != "\n":
line = line[:-1]
fields = line.split('=')
if fields[0] == 'Initial test ID ':
self.ictest = fields[1].lstrip()
def getsetname(self):
try:
return self.ictemp
except AttributeError:
return
if __name__ == "__main__":
c = MyApp()
Application().Run(c)
iset = c.getsetname()
In my class, if I put a break point, self.ictest has a value of 'test' and self.ictemp has a value of {System.Windows.Controls.TextBox:test}, however if I put the break point in my main program for iset, I will get this Value: 'The name iset does not exist in the current context. I really appreciate if you can help me on this issue.
Your problem is, that the code iset = c.getsetname() will only be reached, after the main window is closed. The reason for this is, that Application().Run() contains your "application main loop", which will run until the main window is closed. So in your case, you should implement all interaction logic in MyApp, not in the application entry point. Everything under if __name__ == "__main__" should only be used for initializing some modules or similar things.
If you want to encapsulate some logic, put it in own modules and call it from MyApp. For example if you want to react on some button click, just do this:
# Short
def __init__(self, ...):
# Init component
self.yourButton.Click += self.OnButtonClick
def OnButtonClick(self, sender, args):
MessageBox.Show("Clicked on some button!") # Import Message box before :)
Hope this helps.
EDIT
This is working pretty well:
import wpf
from System.Windows import Window, Application
from System.Windows.Controls import TextBox
class MyApp(Window):
box = None
def __init__(self):
self.Width = 200
self.Height = 200
self.box = TextBox()
self.box.Height = 24
self.box.Width = 150
self.Content = self.box
def getBoxContent(self):
return self.box.Text
if __name__ == "__main__":
c = MyApp()
Application().Run(c)
print (c.getBoxContent())
Info passing
If you want to pass info to and from the ui, just create some class which hold the information. This will be the best solution:
import wpf
from System.Windows import Window, Application
from System.Windows.Controls import TextBox
class Information:
InformationOne = 1
InformationTwo = "Hello World"
class MyApp(Window):
box = None
information = None
def __init__(self, info):
self.information = info
self.Width = 200
self.Height = 200
self.box = TextBox()
self.box.Height = 24
self.box.Width = 150
# Init information
self.box.Text = self.information.InformationTwo
self.Content = self.box
# Information property
#property
def Information(self):
self.information.InformationTwo = self.box.Text
return self.information
if __name__ == "__main__":
info = Information()
c = MyApp(info)
Application().Run(c)
# Get information
print (c.Information.InformationTwo)
I have a simple form with a textBox in it which I am trying to make an user friendly Auto-suggest Textbox..
As per the current scenario I am using AutoCompleteStringCollectionclass bywhich I am able to make textbox show suggestions for the word that starts with the particular Text entered in textbox..
But,I want to make my program as like it should show suggestions even when a part of the string coming from database matches the Textbox.Text.
Presently I am able to filter the data coming from DB based on the userInput by using dataView .But still I am not able to show output on my front end..
I have tried all textbox events like 'KeyPress',KeyDown,KeyUp,TextChanged but its not working....
MyCode::
public partial class Form2 : Form
{
AutoCompleteStringCollection autoCompletefromDB = new AutoCompleteStringCollection();
AutoCompleteStringCollection searchResults = new AutoCompleteStringCollection();
MyLinqDataContext dtcontext = new MyLinqDataContext();
// static string searchChar = "";
SqlConnection con = new SqlConnection("Data Source=DATASERVER\\SQL2K8;Initial Catalog=VTMMedicalContent;Persist Security Info=True;User ID=vtm;Password=M3d!c#l");
DataTable dTable = new DataTable();
SqlCommand cmd;
SqlDataAdapter da;
DataView dtView;
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select DiagnosisName from [VTMMedicalContent].[dbo].[DiagnosisMaster]";
da = new SqlDataAdapter(cmd);
da.Fill(dTable);
dtView = new DataView(dTable);
}
//And My KeyPress Event Code..
private void txtAutoComplete_KeyPress(object sender, KeyPressEventArgs e)
{
if (!Char.IsControl(e.KeyChar))
{
dtView.RowFilter = dtView.Table.Columns[0].ColumnName + " Like '%" + e.KeyChar + "%'";
foreach (DataRowView dtViewRow in dtView)
searchResults.Add(dtViewRow[0].ToString());
txtAutoComplete.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
txtAutoComplete.AutoCompleteSource = AutoCompleteSource.CustomSource;
txtAutoComplete.AutoCompleteCustomSource = searchResults;
}
//MessageBox.Show("The Elements in searchResult are:" + searchResults.Count);
}
I have the tried writing the same codes in KeyDown,KeyUp,TextChanged events but of no use..:(
It only works on Form_Load but that only shows suggestions that matches the starting point of the word..
Create an AutoComplete TextBoxControl
The AutoComplete feature has a couple of quirks that were inherited from its original designed use, the address box of Internet Explorer. This includes emitting the Enter key when you click on an item in the list. Pressing Enter in the address box of IE makes it navigate to the entered URL.
There isn't anything you can do about that, the native interface (IAutoComplete2) has very few options to configure the way it works. It pokes the keystrokes into the text box by faking Windows messages. Which is one way you can tell the difference, the actual key won't be down. Something you can check by pinvoking GetKeyState(), like this:
as an example you can mess with this anyway you like
private void textBox1_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyData == Keys.Enter && GetKeyState(Keys.Enter) < 0) {
Console.WriteLine("Really down");
}
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern short GetKeyState(Keys key);
Greetings;
I'm having a bit of trouble correctly instantiating an Array of System.Drawing.Point instances, and then adding the Array of Points to a GDI+ GraphicsPath instance using IronPython in a WinForms application. The following code compiles or builds correctly under SharpDevelop 3.2 with IronPython 2.6:
import System.Drawing
import System.Drawing.Drawing2D
import System.Windows.Forms
from System import Array
from System.Drawing import Pen, Point
from System.Drawing.Drawing2D import GraphicsPath, CustomLineCap
from System.Windows.Forms import *
class MainForm(Form):
def __init__(self):
self.InitializeComponent()
def InitializeComponent(self):
self.SuspendLayout()
#
# MainForm
#
self.ClientSize = System.Drawing.Size(284, 264)
self.Name = "MainForm"
self.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
self.Text = "GDI Lines"
self.Paint += self.MainFormPaint
self.ResumeLayout(False)
def MainFormPaint(self, sender, e):
graphicContext = e.Graphics
bluePen = Pen(Color.Blue, 1)
points = Array.CreateInstance(Point, 9)
points[0] = Point(10, 10)
points[1] = Point(15, 10)
points[2] = Point(20, 15)
points[3] = Point(20, 20)
points[4] = Point(15, 25)
points[5] = Point(10, 25)
points[6] = Point(5, 20)
points[7] = Point(5, 15)
points[8] = Point(10, 10)
graphicsPath = GraphicsPath()
graphicsPath.AddLines(points)
graphicContext.SmoothingMode = SmoothingMode.AntiAlias
lineCap = CustomLineCap(nil, graphicsPath)
lineCap.BaseInset = 0
lineCap.WidthScale = 1
lineCap.StrokeJoin = LineJoin.Miter
bluePen.CustomStartCap = lineCap
bluePen.CustomEndCap = lineCap
graphicContext.DrawLine(bluePen, 50, 150, 200, 150)
graphicContext.DrawLine(bluePen, 150, 50, 150, 200)
lineCap.Dispose()
graphicsPath.Dispose()
bluePen.Dispose()
Based on the code above, I was expecting to see two perpendicualr blue lines drawn, with a small ellipse at the end of each line. Using the current scipting code above, the GDI+ runtime error red X is drawn. What am I missing or doing incorrectly? Also, is there a simpler or more concise way of instantiating an Array of System.Drawing.Point values?
Thank you in advance for your time and help...
In all fairness, I must say that I did not "Answer my own question" or resolve this issue on my own, but was able to receive outside help from both Matt Ward and Michael Foord. My sincerest thanks to both Matt and Michael for their time, help and patience, and I really appreciate them writing back with their corrections.
The main issue that kept the MainForm.py script from running was the omission on my part of importing the Color class from the System.Drawing namespace, and the SmoothingMode and LineJoin Enumerations from the System.Drawing.Drawing2D namespace. Although my script does not directly instantiate any of the additional enumerations or class, they still must be loaded and referenced from their respective assemblies by the .NET DLR to make them accessible and usable within my script. (Note: Again, thanks to Matt for pointing this out to me; if there are any errors in the explanation, they are mine and not Matt's.)
The original Array instantiation of the GDI+ Point instances was correct, but a more succinct approach is shown in the corrected script below. (Note: Again, my thanks to Michael for pointing out the Array instantiation alternative.)
The corrected and working MainForm.py script is as follows:
import System.Drawing
import System.Drawing.Drawing2D
import System.Windows.Forms
from System import Array
from System.Drawing import Pen, Point, Color
from System.Drawing.Drawing2D import GraphicsPath, CustomLineCap, SmoothingMode, LineJoin
from System.Windows.Forms import *
class MainForm(Form):
def __init__(self):
self.InitializeComponent()
def InitializeComponent(self):
self.SuspendLayout()
#
# MainForm
#
self.ClientSize = System.Drawing.Size(284, 264)
self.Name = "MainForm"
self.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
self.Text = "GDI+ CustomLineCaps"
self.Paint += self.MainFormPaint
self.ResumeLayout(False)
def MainFormPaint(self, sender, e):
graphics = e.Graphics
bluePen = Pen(Color.Blue, 1)
points = Array[Point] \
((Point(10, 10), Point(15, 10), Point(20, 15), \
Point(20, 20), Point(15, 25), Point(10, 25), \
Point(5, 20), Point(5, 15), Point(10, 10)))
graphicsPath = GraphicsPath()
graphicsPath.AddLines(points)
graphics.SmoothingMode = SmoothingMode.AntiAlias
lineCap = CustomLineCap(None, graphicsPath)
lineCap.BaseInset = 0
lineCap.WidthScale = 1
lineCap.StrokeJoin = LineJoin.Miter
bluePen.CustomStartCap = lineCap
bluePen.CustomEndCap = lineCap
graphics.DrawLine(bluePen, 50, 150, 200, 150)
graphics.DrawLine(bluePen, 150, 50, 150, 200)
lineCap.Dispose()
graphicsPath.Dispose()
bluePen.Dispose()