Reading input text through scrolled window? - pygtk

I have created a scrolled window using pyGTK. When I type some text in the scrolled window,that typed text must be written in a file. I have a function which could write to the file. But as and when I go typing some text into the scrolled window that function must be called. If anyone suggest me the solution that would be very helpufull.

import glib, gtk
saveFilePath = 'textview.txt'
isChanged = True
def onBufferChanged(b):
global isChanged
isChanged = True
def onTimeout():
if isChanged:
text = textbuff.get_text(textbuff.get_start_iter(), textbuff.get_end_iter())
open(saveFilePath, 'w').write(text)
isChanged = False
return True ## Continue loop
textview = gtk.TextView()
textbuff = textview.get_buffer()
textbuff.connect('changed', onBufferChanged)
glib.timeout_add_seconds(1, onTimeout)
dialog = gtk.Dialog()
dialog.vbox.pack_start(textview, 1, 1)
dialog.vbox.show_all()
dialog.run()

You should subscribe to change event of text area were you type text and then schedule and execution of function that saves the text to file say each 1 second, so as you type your text would automatically saved. or you could have a background thread that monitors state of that control and save-s it regularly with 1 second delay so that. I think thread way is more correct

Related

Multi-QComboBox Hide/Show Popup on LineEdit Press (PyQT5)

I have created a checkable QComboBox where all the options are checkboxes. Everything works fine, except I can no longer click on the QLineEdit to open/close the combobox pop-up, the way a regular QComboBox would work.
I have tried to apply an event filter to the QLineEdit, as shown below, that should ideally close the combobox pop-up if it is currently open, and open it if it is currently closed. But instead, clicking on QLineEdit only opens the pop-up everytime.
I believe this is because the mouse button press (QEvent.MouseButtonPress) closes the pop-up (hence setting the self.isPopup boolean to False), so the mouse button release (QEvent.MouseButtonRelease) will always open the pop-up. I've tried to get the QCombobox to ignore the MouseButtonPress event, but to no avail. I'm not sure where I've gone wrong here - if anyone has any suggestions, it would be much appreciated.
(Here's the relevant parts of the code)
class CustomComboBox(QtWidgets.QComboBox):
def __init__(self):
super(CustomComboBox, self).__init__()
self.setModel(QtGui.QStandardItemModel(self)) # setting up widget to make it checkable
self.setEditable(True)
self.lineEdit().setReadOnly(True)
self.lineEdit().setPlaceholderText("--Select Option--")
self.isPopup = False # bool to close or open pop up
self.lineEdit().installEventFilter(self) # event filter for lineedit presses
def hidePopup(self):
super().hidePopup()
self.isPopup = False
def showPopup(self):
super().shwoPopup()
self.isPopup = True
def eventFilter(self, widget, event):
if widget == self.lineEdit():
if event.type() == QtCore.QEvent.MouseButtonRelease:
if self.isPopup:
self.hidePopup()
else:
self.showPopup()
return True
elif event.type() == QtCore.QEvent.MouseButtonPress:
event.ignore()
return True
return super(CustomComboBox, self).eventFilter(widget, event)
The problem is caused by the fact that making the combo editable, you actually have two widgets that can handle mouse events, and since QComboBox handles mouse buttons in a specific way (to allow proper popup management) that makes things difficult, because the popup normally closes after the button press.
Since your requirement for the editable line edit is just to write custom text, then just override the paintEvent by slightly changing the default behavior:
class CustomComboBox(QtWidgets.QComboBox):
customText = ''
def setCustomText(self, text):
if self.customText != text:
self.customText = text
self.update()
def paintEvent(self, event):
if not self.customText:
super().paintEvent(event)
return
painter = QStylePainter(self)
painter.setPen(self.palette().color(QPalette.Text))
opt = QStyleOptionComboBox()
self.initStyleOption(opt)
painter.drawComplexControl(QStyle.CC_ComboBox, opt)
opt.text = self.customText
painter.drawControl(QStyle.CE_ComboBoxaLabel, opt)
With the code above, you don't need to make the combo editable, and therefore there is no event filtering.

RadioButtons Highlighting Incorrectly

On my form, I have 4 RadioButtons, each with its appearance set to Button. In my program, I change each of these RadioButton's ForeColour, BackColour and AutoCheck status, as below:
ARadioButton.AutoCheck = False
ARadioButton.BackColor = Color.FromKnownColor(KnownColor.ControlLightLight)
ARadioButton.ForeColor = Color.FromKnownColor(KnownColor.ControlDark)
However, later on, I reset these properties back to default:
ARadioButton.AutoCheck = True
ARadioButton.BackColor = DefaultBackColor
ARadioButton.ForeColor = DefaultForeColor
My issue is that instead of the entire button being highlighted, only the outside is, as shown in the images below.
Originally:
After changes are made and RadioButtons reset to default using code above:
I know this may seem trivial, but I would like the entire RadioButton to be highlighted when the user clicks on the RadioButton, not just the outside.
Is there a way I could somehow reset this?
Try setting the BackColor property to Color.Transparent

InDesign CS6 scripting - Add overflowing content on next page(s)

After I imported XML-Data into an InDesign document I see that red plus symbol at the textframe at the end of the first page.
How can I insert/move that content on next page(s) with scripting?
This script should do what you want. :)
var myDoc = app.activeDocument;
var myFrames = myDoc.textFrames;
while (myFrames[0].overflows === true) {
var myNewPage = myDoc.pages.add();
var myMargin = myNewPage.marginPreferences;
var myBounds = [myMargin.top, myMargin.left, myDoc.documentPreferences.pageHeight - myMargin.bottom, myDoc.documentPreferences.pageWidth - myMargin.right];
var myOldRuler = myDoc.viewPreferences.rulerOrigin;
myDoc.viewPreferences.rulerOrigin = RulerOrigin.pageOrigin;
with(myDoc.pages[-1].textFrames.add()) {
geometricBounds = myBounds;
previousTextFrame = myDoc.pages[-2].textFrames[0];
}
myDoc.viewPreferences.rulerOrigin = myOldRuler;
}
The TextFrame object has a property overflows: Bool, readonly. If true, the story has overset text.
The TextFrame object has also a property nextTextFrame: r/w The next text frame in the thread. Can return: TextFrame or TextPath. Can also accept: NothingEnum enumerator.
http://jongware.mit.edu/idcs6js/pc_TextFrame.html
not sure you need scripting... if the document is set up as a template simply click the plus sign and "capture" the contents. then move to the next page and click where you want the text to reflow to. adjust the text boxes as needed to suit.
For the non-scripting solution to flowing overset text frames, after adding a new page, hold down shift before clicking. This will cause the text to autoflow on as many pages as it takes until there is no longer an overset text frame.
From CS4, we can enable the "Smart Text Reflow" to automatically flow text to the available content. It will insert the pages automatically.
Edit Menu \ Preferences \ Type \ Smart Text Reflow
Also, it comes with "Delete Empty Pages", so when the content goes less, then it will automatically remove the empty pages accordingly.

creating a static vb.net "app" that consist of a single picture

I need to create a vb.net program that consists of a unmovable, always on top bitmap, with no menu bar or anything, and does not show up in the task bar as program.
It needs to always start in the same place.
Essentially I need to mask a part of the screen by using a bitmap that blends into the scenery.
I am not sure which properties I need to tweak to achieve all of this.
Just to try changing the properties until you get the right result, but the below is probably sort of what you're looking for.
StartPosition = Manual
ShowInTaskBar = False
SizeGripStyle = Hide
TopMost = True
ControlBox = False
FormBorderStyle = None
Location = X, Y 'wherever it should be

Best way to combine Play and Pause button?

this is more of an advise thread I guess.
I've been wondering how one could create a button which display "play" when it's not pressed. And then shows "pause" once it's pressed. And visa versa when it's pressed again.
I had a similar problem when trying to create an expand panel button, but that was easy because I could just set a variable to true or false if PanelCollapsed was true.
But in this case I couldn't find any property in a button that I could query.
So I came up with this but I can't help thinking that this is a rather unsmart way of doing it?
If isPlay = True Then
If isPaused = False Then
btnPlay.Image = Image.FromFile("iconPause.png")
isPaused = True
isPlay = False
End If
GoTo Endline
End If
If isPlay = False Then
If isPaused = True Then
btnPlay.Image = Image.FromFile("iconPlay.png")
isPaused = False
isPlay = True
End If
End If
Endline:
How about using only one variable and code like this:
If isPlay Then
btnPlay.Image = Image.FromFile("iconPause.png")
else
btnPlay.Image = Image.FromFile("iconPlay.png")
End If
isPlay = not isPlay
You can use the "Tag" property. Its type is "object" so you can use any object you want, but in your case a string will do:
If Button1.Tag = "Pause" Then
Button1.Image = Image.FromFile("iconPlay.png")
Button1.Tag = "Play"
Else
Button1.Image = Image.FromFile("iconPause.png")
Button1.Tag = "Pause"
End If
Most .NET WinForm controls have a 'Tag' property (a button has one). You can set the Tag to be anything you want. An easy way to do this is to set the 'Tag' property to a boolean with the state of the button.
Just an idea...sure there are many other approaches.
UPDATE:
Otherwise, you can maintain the state of the button in your application as its own member variable. This might have several advantages because you can pass this state to other controls that might need it. The only weakness with this approach is that the state must be maintained separately.
If you have a fairly straight-forward implementation, use the Tag property.
A contrary opinion ...
... while other answers have given you some techniques to achieve your desired result, I'm going to ask you to reconsider your UI design.
Dual state buttons - ones that alternate purpose when clicked - can be a source of user frustation.
Here are two scenarios.
Scenario #1 ... if the users machine is under load (for any reason), there may be a perceptible delay between the users actual click on your button and when your click handler is executed.
Normally the time between click and handler is a few milliseconds or less, but it can run to several seconds. If this happens when the user clicks on a dual state button, they are likely to click the button again. Net effect, when the application catches up, is to toggle on, then immediately off again.
Scenario #2 ... many users habitually double click everything. Even experienced users who've been using computers for years may have this weird habit. When they try to press a dual state button, guess what happens ... the action toggles on, then immediately off again.
There are at least two solutions ...
Solution #1 ... use two buttons, one for "On", one for "Off".
Solution #2 ... write some debouncing code to suppress the effect of a second click if processed immediately (ie: < 75ms) after the first.
I don't personally use Visual Basic, but I do know that Buttons in Windows Forms have a property called 'Tag'. It is of the generic object type, so you can save whatever state you want, and just use casting to get the value back out.
How about using the "Image" property?
Rem form initialization
ImagePlay = Image.FromFile("iconPlay.png")
ImagePause = Image.FromFile("iconPause.png")
Button1.Image = ImagePlay
.
.
.
Rem on button1 click
If Button1.Image = ImagePlay Then
Button1.Image = ImagePause
Else
Button1.Image = ImagePlay
End If