How do you put the fullname (from notepad user; pass; fullname) to show at the Qlineedit widget in the second class (which is also the second GUI)
FIRST CLASS
from inventoryform import InventoryDialog
class LoginDialog(QtWidgets.QDialog, Ui_loginform):
isLogged = QtCore.pyqtSignal()
def __init__(self, parent=None):
def login_button_clicked(self):
import csv
with open('user.txt', newline='') as f:
reader = csv.reader(f, delimiter=';')
for line in reader:
us, pa, fn = line
if self.username_line.text() == us and self.password_line.text() == pa:
QtWidgets.QMessageBox.information(self, "LOGIN", "LOGIN SUCCESSFUL!")
self.isLogged.emit()
a = QLineEdit()
a.setText(fn)
usershowname_line.append(a)
self.close()
return
else:
QtWidgets.QMessageBox.information(self, "LOGIN FAILED", "LOGIN FAILED!")
def exit_button_clicked(self):
self.close()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
loginform_window = LoginDialog()
x = InventoryDialog()
loginform_window.isLogged.connect(x.show)
x.isLogout.connect(loginform_window.show)
loginform_window.show()
sys.exit(app.exec_())
SECOND CLASS
class InventoryDialog(QtWidgets.QDialog, Ui_inventoryform):
isLogout = QtCore.pyqtSignal()
def __init__(self, parent=None):
QtWidgets.QDialog.__init__(self, parent)
self.setupUi(self)
self.signout_button.clicked.connect(self.onSignout_button)
def onSignout_button(self):
self.isLogout.emit()
self.close()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
inventoryform_window = InventoryDialog()
inventoryform_window.show()
sys.exit(app.exec_())
Here's the QlineEdit which object name is usershowname_line from the second gui:
You have to create a signal that can send a string (pyqtSignal (str)), this will emit before closing the window. To show it we must connect it to setText of QLineEdit (In your case it replaces your_lineedit with the name of your QLineEdit). All of the above is shown in the following part:
class LoginDialog(QtWidgets.QDialog, Ui_loginform):
isLogged = QtCore.pyqtSignal()
dataSignal = QtCore.pyqtSignal(str)
[...]
def login_button_clicked(self):
[...]
self.dataSignal.emit("user: {}, pass: {}, fullname: {}".format(us, pa, fn))
self.isLogged.emit()
[...]
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
loginform_window = LoginDialog()
x = InventoryDialog()
loginform_window.isLogged.connect(x.show)
loginform_window.dataSignal.connect(x.your_lineedit.setText)
# ^^^^^^^^^^^^^
x.isLogout.connect(loginform_window.show)
loginform_window.show()
sys.exit(app.exec_())
Related
I built a google search suggestion completer for my simple browser built with pyqt5 and python. code is below.
self.url_bar = QLineEdit()
self.url_bar.textChanged.connect(self.suggest)
def suggest(self):
suggestlist =[]
term = self.url_bar.text()
if not (validators.url(term) and term != '') :
url = f"http://toolbarqueries.google.com/complete/search?q={term}&output=toolbar&hl=en"
suggestions = requests.get(url)
suggestions = ET.fromstring(suggestions.content)
for data in suggestions.iter('suggestion'):
suggestlist.append(data.attrib['data'])
suggester = QCompleter(suggestlist)
self.url_bar.setCompleter(suggester)
this generates the suggestions correctly but browser is accidentially closed. please help me.
Based on my previous post and making some modifications you can have the following solution. I don't use requests as it potentially blocks the eventloop if the request takes too long.
import xml.etree.ElementTree as ET
from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork
class SuggestionModel(QtGui.QStandardItemModel):
finished = QtCore.pyqtSignal()
error = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(SuggestionModel, self).__init__(parent)
self._manager = QtNetwork.QNetworkAccessManager(self)
self._reply = None
#QtCore.pyqtSlot(str)
def search(self, text):
self.clear()
if self._reply is not None:
self._reply.abort()
if text:
r = self.create_request(text)
self._reply = self._manager.get(r)
self._reply.finished.connect(self.on_finished)
loop = QtCore.QEventLoop()
self.finished.connect(loop.quit)
loop.exec_()
def create_request(self, text):
url = QtCore.QUrl("http://toolbarqueries.google.com/complete/search")
query = QtCore.QUrlQuery()
query.addQueryItem("q", text)
query.addQueryItem("output", "toolbar")
query.addQueryItem("hl", "en")
url.setQuery(query)
request = QtNetwork.QNetworkRequest(url)
return request
#QtCore.pyqtSlot()
def on_finished(self):
reply = self.sender()
if reply.error() == QtNetwork.QNetworkReply.NoError:
content = reply.readAll().data()
suggestions = ET.fromstring(content)
for data in suggestions.iter("suggestion"):
suggestion = data.attrib["data"]
self.appendRow(QtGui.QStandardItem(suggestion))
self.error.emit("")
elif reply.error() != QtNetwork.QNetworkReply.OperationCanceledError:
self.error.emit(reply.errorString())
else:
self.error.emit("")
self.finished.emit()
reply.deleteLater()
self._reply = None
class Completer(QtWidgets.QCompleter):
def splitPath(self, path):
self.model().search(path)
return super(Completer, self).splitPath(path)
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self._model = SuggestionModel(self)
completer = Completer(self, caseSensitivity=QtCore.Qt.CaseInsensitive)
completer.setModel(self._model)
lineedit = QtWidgets.QLineEdit()
lineedit.setCompleter(completer)
label = QtWidgets.QLabel()
self._model.error.connect(label.setText)
lay = QtWidgets.QFormLayout(self)
lay.addRow("Location: ", lineedit)
lay.addRow("Error: ", label)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.resize(400, w.sizeHint().height())
w.show()
sys.exit(app.exec_())
How can I use the window handle to screenshot a running instance of Notepad? I already figured out how to successfully screenshot a widget within the python dialog itself. I have also figured out how to get the handle of the running notepad window. I'm stuck on trying to capture the screenshot of the window using the handle.
import os, sys
from PySide import QtGui, QtCore
import ctypes
class GuiCaptureWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(GuiCaptureWindow, self).__init__(parent)
self.resize(250, 100)
self.setWindowTitle('GUI Capture')
# console
self.ui_capture = QtGui.QPushButton('Capture')
main_layout = QtGui.QGridLayout()
main_layout.addWidget(self.ui_capture)
main_widget = QtGui.QWidget()
main_widget.setLayout(main_layout)
self.setCentralWidget(main_widget)
# signals
self.ui_capture.clicked.connect(self.capture)
def getRelativeFrameGeometry(self, widget):
g = widget.geometry()
fg = widget.frameGeometry()
return fg.translated(-g.left(),-g.top())
def screenCaptureWidget(self, widget, filename, fileformat='.png'):
rfg = self.getRelativeFrameGeometry(widget)
pixmap = QtGui.QPixmap.grabWindow(widget.winId(),
rfg.left(), rfg.top(),
rfg.width(), rfg.height())
filepath = os.path.abspath(filename + fileformat)
pixmap.save(filepath)
os.system("start " + filepath)
def capture(self):
self.collect_window_titles()
self.screenCaptureWidget(self.ui_capture, 'test')
def collect_window_titles(self):
EnumWindows = ctypes.windll.user32.EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
GetWindowText = ctypes.windll.user32.GetWindowTextW
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
IsWindowVisible = ctypes.windll.user32.IsWindowVisible
apps = []
def foreach_window(hwnd, lParam):
if IsWindowVisible(hwnd):
length = GetWindowTextLength(hwnd)
buff = ctypes.create_unicode_buffer(length + 1)
GetWindowText(hwnd, buff, length + 1)
if buff.value:
apps.append({'title': buff.value, 'handle': hwnd})
return True
EnumWindows(EnumWindowsProc(foreach_window), 0)
for app in apps:
print app
if app['title'] == 'Untitled - Notepad':
print 'CAPTURE'
return
def main():
app = QtGui.QApplication(sys.argv)
ex = GuiCaptureWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I'm facing an issue to save a complete state of a Qt window application.
What I'd like to di is save a file which contains everything about the window and then, if I want, I could reload it to obtain the same window with all previous variable in it (reload their values)
For instance, I've this code
import pickle
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
class SurfViewer(QMainWindow):
def __init__(self, parent=None):
super(SurfViewer, self).__init__()
self.parent = parent
self.centralWidget = QWidget()
self.color = self.centralWidget.palette().color(QPalette.Background)
self.setCentralWidget(self.centralWidget)
self.plotview = QGroupBox(" ")
self.layout_plotview = QVBoxLayout()
self.test = QLineEdit('0.0')
self.Button_Loadstate = QPushButton('Load state')
self.Button_Savestate = QPushButton('Save state')
self.layout_plotview.addWidget(self.test)
self.layout_plotview.addWidget(self.Button_Savestate)
self.layout_plotview.addWidget(self.Button_Loadstate)
self.centralWidget.setLayout(self.layout_plotview)
self.Button_Savestate.clicked.connect(self.Savestate)
self.Button_Loadstate.clicked.connect(self.Loadstate)
def Savestate(self,):
fileName = QFileDialog.getSaveFileName(self,'Save State')
if (fileName[0] == '') :
return
file_pi = open(fileName[0] + '.state', 'wb')
pickle.dump(self, file_pi)
file_pi.close()
return
def Loadstate(self,):
fileName = QFileDialog.getOpenFileName(self,'Load State' , "", "data files (*.state)")
if (fileName[0] == '') :
return
filehandler = open(fileName[0], 'rb')
self = pickle.load(filehandler)
filehandler.close()
return
def main():
app = QApplication(sys.argv)
ex = SurfViewer(app)
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
which give me this :
I create a window with a QLineEdit and two buttons (one for saving and one for loading). Then I use pickle to save the self of the SurfViewer class instance in a Savestatefunction. Then I try to reload the previous state with pickle self = pickle.load(filehandler). It seems that it will not be so simple because I cannot assign the self variable.
If anyone could give some insights to perform that without saving every variable by hand.
This is a pyside GUI, I have created 2 panel in 2 different .py files, main.py and sub.py each panel will display a we browser 'QWebView'. Currently when user press the button on main.py it will redirect the user to a page e.g "www.google" and user will have to click the button on sub.py to be redirected to e.g"www.facebook.com" they work as a indipendent function.
I would like to ask is there a way to link both together where user press the button on main.py and both webbrower will change together?
Yes, you can have multiple items triggered by the same connection.
QObject::connect(myButton, SIGNAL(clicked()),
this, SLOT(launchGoogleSiteOnBrowserA());
QObject::connect(myButton, SIGNAL(clicked()),
pointerToOtherClass, SLOT(launchFacebookSiteOnBrowserB());
http://qt-project.org/doc/qt-4.8/signalsandslots.html
EDIT: Following some another answer about using signals and slots in PyQt...
https://stackoverflow.com/a/7618282/999943
Here is a way to do it in PyQt:
widget.pyw
from PyQt4 import QtCore, QtGui
from mybrowser import Browser
class Widget(QtGui.QWidget):
def __init__(self):
super(Widget, self).__init__()
self.myButton = QtGui.QPushButton('Open Facebook and Google')
self.myHLayout = QtGui.QHBoxLayout()
self.myVLayout = QtGui.QVBoxLayout()
self.myVLayout.addWidget(self.myButton)
url = QtCore.QUrl('http://www.yahoo.com')
self.browserLHS = Browser(url)
self.browserRHS = Browser(url)
self.myHLayout.addWidget(self.browserLHS)
self.myHLayout.addWidget(self.browserRHS)
QtCore.QObject.connect(self.myButton, QtCore.SIGNAL("clicked()"), self.changePageOnBothBrowsers )
self.myVLayout.addLayout(self.myHLayout)
self.setLayout(self.myVLayout)
def changePageOnBothBrowsers(self):
self.browserLHS.load(QtCore.QUrl.fromUserInput('google.com'))
self.browserRHS.load(QtCore.QUrl.fromUserInput('facebook.com'))
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
widget = Widget()
widget.show()
sys.exit(app.exec_())
mybrowser.pyw
from PyQt4 import QtCore, QtGui, QtNetwork, QtWebKit
import jquery_rc
class Browser(QtWebKit.QWebView):
def __init__(self, url):
super(Browser, self).__init__()
self.progress = 0
fd = QtCore.QFile(":/jquery.min.js")
if fd.open(QtCore.QIODevice.ReadOnly | QtCore.QFile.Text):
self.jQuery = QtCore.QTextStream(fd).readAll()
fd.close()
else:
self.jQuery = ''
QtNetwork.QNetworkProxyFactory.setUseSystemConfiguration(True)
self.load(url)
self.loadFinished.connect(self.adjustLocation)
self.titleChanged.connect(self.adjustTitle)
self.loadProgress.connect(self.setProgress)
self.loadFinished.connect(self.finishLoading)
self.locationEdit = QtGui.QLineEdit(self)
self.locationEdit.setSizePolicy(QtGui.QSizePolicy.Expanding,
self.locationEdit.sizePolicy().verticalPolicy())
self.locationEdit.returnPressed.connect(self.changeLocation)
def adjustLocation(self):
self.locationEdit.setText(self.url().toString())
def changeLocation(self):
url = QtCore.QUrl.fromUserInput(self.locationEdit.text())
self.load(url)
self.setFocus()
def adjustTitle(self):
if 0 < self.progress < 100:
self.setWindowTitle("%s (%s%%)" % (self.title(), self.progress))
else:
self.setWindowTitle(self.title())
def setProgress(self, p):
self.progress = p
self.adjustTitle()
def finishLoading(self):
self.progress = 100
self.adjustTitle()
self.page().mainFrame().evaluateJavaScript(self.jQuery)
#if __name__ == '__main__':
#
# import sys
#
# app = QtGui.QApplication(sys.argv)
#
# if len(sys.argv) > 1:
# url = QtCore.QUrl(sys.argv[1])
# else:
# url = QtCore.QUrl('http://www.google.com/ncr')
#
# browser = Browser(url)
# browser.show()
#
# sys.exit(app.exec_())
Hope that helps.
I've implemented a very simple log viewer in Python using PyQt4.
I am interested in using it to follow the execution of a program, so the list view has to be refreshed when a new line is appended to the log file.
Here is my implementation (without the watch):
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class LogEntryModel(QAbstractListModel):
def __init__(self, logfile, parent=None):
super(LogEntryModel, self).__init__(parent)
self.slurp(logfile)
def rowCount(self, parent=QModelIndex()):
return len(self.entries)
def data(self, index, role):
if index.isValid() and role == Qt.DisplayRole:
return QVariant(self.entries[index.row()])
else:
return QVariant()
def slurp(self, logfile):
self.entries = []
with open(logfile, 'rb') as fp:
for line in fp.readlines():
tokens = line.strip().split(' : ')
sender = tokens[2]
message = tokens[4]
entry = "%s %s" % (sender, message)
self.entries.append(entry)
class LogViewerForm(QDialog):
def __init__(self, logfile, parent=None):
super(LogViewerForm, self).__init__(parent)
# build the list widget
list_label = QLabel(QString("<strong>MoMo</strong> Log Viewer"))
list_model = LogEntryModel(logfile)
self.list_view = QListView()
self.list_view.setModel(list_model)
list_label.setBuddy(self.list_view)
# define the layout
layout = QVBoxLayout()
layout.addWidget(list_label)
layout.addWidget(self.list_view)
self.setLayout(layout)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = LogViewerForm(sys.argv[1])
form.show()
app.exec_()
As presented, the application works as expected: open the file, parse the contents (split at ' : ' and create a list), and display the list using a QListView.
There is a QFileSystemWatcher class which emits a fileChanged signal, but I don't know where to connect it and how to trigger an add a row to the data and refresh the view event.
Any help?
Thanks.
I am quite new to python and pyqt, but this "works" here:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class LogEntryModel(QAbstractListModel):
def __init__(self, logfile, parent=None):
super(LogEntryModel, self).__init__(parent)
self.slurp(logfile)
self.logfile = logfile
def rowCount(self, parent=QModelIndex()):
return len(self.entries)
def data(self, index, role):
if index.isValid() and role == Qt.DisplayRole:
return QVariant(self.entries[index.row()])
else:
return QVariant()
def slurp(self, logfile):
self.entries = []
with open(logfile, 'rb') as fp:
for line in fp.readlines():
tokens = line.strip().split(' : ')
sender = tokens[2]
message = tokens[4]
entry = "%s %s" % (sender, message)
self.entries.append(entry)
class LogViewerForm(QDialog):
def __init__(self, logfile, parent=None):
super(LogViewerForm, self).__init__(parent)
self.watcher = QFileSystemWatcher([logfile], parent=None)
self.connect(self.watcher, SIGNAL('fileChanged(const QString&)'), self.update_log)
# build the list widget
list_label = QLabel(QString("<strong>MoMo</strong> Log Viewer"))
list_model = LogEntryModel(logfile)
self.list_model = list_model
self.list_view = QListView()
self.list_view.setModel(self.list_model)
list_label.setBuddy(self.list_view)
# define the layout
layout = QVBoxLayout()
layout.addWidget(list_label)
layout.addWidget(self.list_view)
self.setLayout(layout)
def update_log(self):
print 'file changed'
self.list_model.slurp(self.list_model.logfile)
self.list_view.updateGeometries()
if __name__ == "__main__":
app = QApplication(sys.argv)
form = LogViewerForm(sys.argv[1])
form.show()
app.exec_()
But be aware that this is probably not a good way to do it.
You might want to stream the logfile...
Maybe somebody more experienced can help out.