How to make one single scroll bar for two QTextEdit, pyqt4, python. Or how to synchronize two scrollbars of two QTextEdit. For simultaneous scrolling texts.
Pyqt4, python.
Cross-connect the value changed signals of all the scrollbars:
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.edit1 = QtGui.QTextEdit(self)
self.edit2 = QtGui.QTextEdit(self)
layout = QtGui.QHBoxLayout(self)
layout.addWidget(self.edit1)
layout.addWidget(self.edit2)
self.edit1.horizontalScrollBar().valueChanged.connect(
self.edit2.horizontalScrollBar().setValue)
self.edit1.verticalScrollBar().valueChanged.connect(
self.edit2.verticalScrollBar().setValue)
self.edit2.horizontalScrollBar().valueChanged.connect(
self.edit1.horizontalScrollBar().setValue)
self.edit2.verticalScrollBar().valueChanged.connect(
self.edit1.verticalScrollBar().setValue)
text = '\n'.join(name for name in dir(QtCore))
self.edit1.setText(text)
self.edit2.setText(text)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 600, 400)
window.show()
sys.exit(app.exec_())
Related
I am programming a simple GUI, that will open a opencv window at a specific point. This window has some very basic keyEvents to control it. I want to advance this with a few functions. Since my QtGui is my Controller, I thought doing it with the KeyPressedEvent is a good way. My Problem is, that I cannot fire the KeyEvent, if I am active on the opencv window.
So How do I fire the KeyEvent, if my Gui is out of Focus?
Do I really need to use GrabKeyboard?
The following code reproduces my Problem:
import sys
from PyQt5.QtWidgets import (QApplication, QWidget)
from PyQt5.Qt import Qt
import cv2
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.first = True
def openselect(self):
im = cv2.imread(str('.\\images\\Steine\\0a5c8e512e.jpg'))
self.r = cv2.selectROI("Image", im)
def keyPressEvent(self, event):
if event.key() == Qt.Key_Space and self.first:
self.openselect()
self.first = False
print('Key Pressed!')
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
The keyPressEvent method is only invoked if the widget has the focus so if the focus has another application then it will not be notified, so if you want to detect keyboard events then you must handle the OS libraries, but in python they already exist libraries that report those changes as pyinput(python -m pip install pyinput):
import sys
from PyQt5 import QtCore, QtWidgets
from pynput.keyboard import Key, Listener, KeyCode
class KeyMonitor(QtCore.QObject):
keyPressed = QtCore.pyqtSignal(KeyCode)
def __init__(self, parent=None):
super().__init__(parent)
self.listener = Listener(on_release=self.on_release)
def on_release(self, key):
self.keyPressed.emit(key)
def stop_monitoring(self):
self.listener.stop()
def start_monitoring(self):
self.listener.start()
class MainWindow(QtWidgets.QWidget):
pass
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
monitor = KeyMonitor()
monitor.keyPressed.connect(print)
monitor.start_monitoring()
window = MainWindow()
window.show()
sys.exit(app.exec_())
I am trying to draw a dot on my main window, but the dot is not shown.
I've tried bounding mousePressEvent to paintEvent, but it didn't work as well. Here's current version of my code(which is not working too). Also I tried place a point with drawPoint method and it didn't work too.
import sys
from PyQt5 import QtWidgets, QtGui, QtCore, uic
class GUI(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi('gui.ui', self)
self.setFixedSize(self.size())
self.show()
def mousePressEvent(self, e):
print(e.pos())
qp = QtGui.QPainter()
qp.begin(self)
qp.setPen(QtCore.Qt.red)
qp.drawEllipse(e.pos().x(), e.pos().y(), 10, 10)
qp.end()
self.update()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = GUI()
sys.exit(app.exec_())
I know that mousePressEvent is working since I get coords of the click.
I am okay to change methods of dot-placing or type of dots to place, but it should have customizable color and size.
You should only draw within the paintEvent method, and this paint does not save memory so if you want to graph several points you must store them in some container, for example using QPolygon.
paintEvent() is called every time you call update() or repaint(), for example it is called every time it is resized, the window is moved, etc.
import sys
from PyQt5 import QtWidgets, QtGui, QtCore, uic
class GUI(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi('gui.ui', self)
self.setFixedSize(self.size())
self.show()
self.points = QtGui.QPolygon()
def mousePressEvent(self, e):
self.points << e.pos()
self.update()
def paintEvent(self, ev):
qp = QtGui.QPainter(self)
qp.setRenderHint(QtGui.QPainter.Antialiasing)
pen = QtGui.QPen(QtCore.Qt.red, 5)
brush = QtGui.QBrush(QtCore.Qt.red)
qp.setPen(pen)
qp.setBrush(brush)
for i in range(self.points.count()):
qp.drawEllipse(self.points.point(i), 5, 5)
# or
# qp.drawPoints(self.points)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = GUI()
sys.exit(app.exec_())
If I use tkinter, I can set the option indicatoron = 0, and get an expected effect.
This effect can be achieved with a group of QPushButton, and some additional code, I suppose.
But is it a true way? Maybe, PyQt has an option, as tkinter?
This code gave me an expected effect from tkinter.
from tkinter import *
root = Tk()
var = IntVar()
button1 = Radiobutton(root,indicatoron=0,text=' One Button ',variable=var,value=1)
button2 = Radiobutton(root,indicatoron=0,text=' Two Button ',variable=var,value=2)
button3 = Radiobutton(root,indicatoron=0,text='Three Button',variable=var,value=3)
button1.place(x=4, y=4)
button2.place(x=4, y=30)
button3.place(x=4, y=56)
mainloop()
In PyQt, you can use QPushButton and a QButtonGroup:
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
layout = QtGui.QVBoxLayout(self)
self.buttonGroup = QtGui.QButtonGroup(self)
for text in 'One Two Three'.split():
button = QtGui.QPushButton(text)
button.setCheckable(True)
layout.addWidget(button)
self.buttonGroup.addButton(button)
self.buttonGroup.buttonClicked.connect(self.handleButtons)
def handleButtons(self, button):
print('Button %s Clicked' % button.text())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
New to PyQt5... Here is a very basic question.
I would like to add an image inside the layout of a widget. This widget is the Main Window / root widget of my application. I use the following code, but I get an error message.
import sys
from PyQt5.QtGui import QImage
from PyQt5.QtWidgets import *
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(300,300,300,220)
self.setWindowTitle("Hello !")
oImage = QImage("backgound.png")
oLayout = QVBoxLayout()
oLayout.addWidget(oImage)
self.setLayout(oLayout)
self.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
oMainwindow = MainWindow()
sys.exit(app.exec_())
TypeError: QBoxLayout.addWidget(QWidget, int stretch=0, Qt.Alignment alignment=0): argument 1 has unexpected type 'QImage'
Apparently a QLayoutWidget does not accept a QImage as an input. Is there a workaround to have an image appear as a brackground in a QWidget ?
The QVBoxLayout class lines up widgets vertically.
documentation QVBoxLayout
QImage is no widget.
on many widgets e.g. QmainWindow, QLabel you can use
widget.setStyleSheet(„ background-image: url(backgound.png);“)
on my machine this doesn't work with QWidget. In this case you can use the following rewrite of your code:
import sys
from PyQt5.QtCore import QSize
from PyQt5.QtGui import QImage, QPalette, QBrush
from PyQt5.QtWidgets import *
class MainWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
self.setGeometry(100,100,300,200)
oImage = QImage("test.png")
sImage = oImage.scaled(QSize(300,200)) # resize Image to widgets size
palette = QPalette()
palette.setBrush(QPalette.Window, QBrush(sImage))
self.setPalette(palette)
self.label = QLabel('Test', self) # test, if it's really backgroundimage
self.label.setGeometry(50,50,200,50)
self.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
oMainwindow = MainWindow()
sys.exit(app.exec_())
I've got a simple tray icon application, but "About" context menu item doesn't work at all.
I'm definitly mising something simple, but important here.
The question is what should i fix to see "About" menu item working?
import sys
from PyQt4 import QtCore
from PyQt4 import QtGui
class SystemTrayIcon(QtGui.QSystemTrayIcon):
def __init__(self, parent=None):
QtGui.QSystemTrayIcon.__init__(self, parent)
self.setIcon(QtGui.QIcon("icon.png"))
self.iconMenu = QtGui.QMenu(parent)
appabout = self.iconMenu.addAction("About")
appexit = self.iconMenu.addAction("Exit")
self.setContextMenu(self.iconMenu)
self.connect(appabout,QtCore.SIGNAL('triggered()'),self.showAbout)
self.connect(appexit,QtCore.SIGNAL('triggered()'),self.appExit)
self.show()
def showAbout(self):
QtGui.QMessageBox.information(self, self.tr("About app"), self.tr("My text here."))
def appExit(self):
sys.exit()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
trayIcon = SystemTrayIcon()
trayIcon.show()
sys.exit(app.exec_())
My solution is
def showAbout(self):
QtGui.QMessageBox.information(QtGui.QWidget(), self.tr("About Tunarium"), self.tr("Your text here."))