Adding a leaflet map to PyQt5 - python

I am new to Qt and PyQt and I appreciate it if someone can help me with this. I am trying to add a leaflet map to a GUI that I am creating using Qt designer and Python. Since there is no such widget, I create a simple Widget in the Qt Designer and promote it to a "LeafWidget" as shown below:
I save this file as (user_interface.ui) and then in my index.py file (under the same folder), I use the class leafWidget (with the same name as what defined in the Qt Designer) to define this new widget. I'm not sure if it is right or not. My "index.py" file that I run is as below.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from pyqtlet import L, MapWidget
from PyQt5.uic import loadUiType
ui,_=loadUiType('user_interface.ui')
class LeafWidget (QWidget):
def __init__(self):
QWidget.__init__(self)
self.mapWidget = MapWidget()
self.map = L.map(self.mapWidget)
self.map.setView([39.764075, -86.159019], 10)
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(self.map)
self.layout = QVBoxLayout(self)
self.layout.addWidget(self.mapWidget)
self.show()
class MainApp(QMainWindow, ui):
def __init__(self):
QMainWindow.__init__(self)
self.setupUi(self)
self.mainWindow_tabWidget.setCurrentIndex(1)
def main():
app=QApplication(sys.argv)
window = MainApp()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
When I run it, it does open up the window, but the place for the map widget is empty as you see below. Am I defining this class correctly? In my MainApp class, do I need to add this new custom widget somehow? I don't get any specific errors in my debug console, So I'm not sure what I am missing.

Related

How application structure should looks like?

I'm trying to create a small database app to keep all clients inside. I would like to write GUI using PyQt5. I have a problem with understanding how app structure should looks like.
I'd like to have a main class which starts the app and I want to seperate GUI, DB and Main classes in different files.
You can see my code snippets bellow. It don't work because some variables are not recognized and accually I don't understand why.
My thoughts:
1. Window, tab1 objects will be created in main class init function
2. When window, tab1 instances were created, the methods inside it's init will be called
3. I have window, tab1 objects and it's variables are available for themselves
window.gbT1Main.setLayout(T1LayMain) is not defined for TabNewClient class. Why ? How should I change my code to achieve above requirements? Please explain me how should I connect my classes :(
Window and TabNewClient class (window, tab1)
from PyQt5.QtWidgets import QApplication, QDialog, QTabWidget, QGroupBox, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QFormLayout, QLineEdit, QDateEdit, QTextEdit, QRadioButton, QGridLayout
import sys
import datetime
class Window(QDialog):
def __init__(self):
super().__init__()
self.InitWindow()
def InitWindow(self):
# create tab widget
self.tab = QTabWidget()
# create MainWindow groupbox
self.gbMainWindow = QGroupBox()
# TAB groupBoxes
self.gbT1Main = QGroupBox()
self.gbT2Main = QGroupBox("Main2")
self.gbT3Main = QGroupBox("Main3")
# Adding tabs
self.tab.addTab(self.gbT1Main, "Dodaj klienta")
self.tab.addTab(self.gbT2Main, "Wyszukaj")
self.tab.addTab(self.gbT3Main, "Statystki")
# Setting MainWindow title
self.setWindowTitle("MEDIKAP - gabinet medycyny pracy")
# Main Window Layout
self.layMainWindow = QHBoxLayout()
# Set MainWindow Layout
self.layMainWindow.addWidget(self.tab)
self.gbMainWindow.setLayout(self.layMainWindow)
# set MainWindow layout visible
self.setLayout(self.layMainWindow)
#show window
self.show()
class TabNewClient:
def __init__(self):
self.CreateTab1Layout()
def CreateTab1Layout(self):
self.gbAddClient = QGroupBox("Dane klienta")
self.gbRodzajBadania = QGroupBox("Podstawa prawna")
self.gbDane = QGroupBox()
self.gbComment = QGroupBox("Komentarz")
self.gbButtons = QGroupBox()
# TAB1 - layouts
T1LayMain = QVBoxLayout()
layDane = QHBoxLayout()
# TAB1
layDane.addWidget(self.gbAddClient)
layDane.addWidget(self.gbRodzajBadania)
self.gbDane.setLayout(layDane)
# TAB1 - set layout to Main
T1LayMain.addWidget(self.gbDane)
T1LayMain.addWidget(self.gbComment)
T1LayMain.addWidget(self.gbButtons)
window.gbT1Main.setLayout(T1LayMain)
Main class:
from PyQt5.QtWidgets import QApplication
import sys
from guiv3 import Window, TabNewClient
class Main:
def __init__(self):
window = Window()
tab1 = TabNewClient()
if __name__ == "__main__":
app = QApplication(sys.argv)
main = Main()
app.exec_()
error:
window.gbT1Main.setLayout(T1LayMain)
NameError: name 'window' is not defined
To answer the question of why you get an error about 'window' not being defined, I believe it's because there is no window variable in the TabNewClient class. It looks like you're attempting to refer to the window defined in Main, but that won't work since that variable isn't in the scope of the TabNewClient class. My guess is that you're going to run into the same issue with gbT1Main, since that is outside the scope of the TabNewClient class as well.
Edit: I think I understand what you're attempting here. You want the gbT1Main related tab in window to hold the layout from tab1. To do that, you will need to set window's layout in Main:
from PyQt5.QtWidgets import QApplication
import sys
from guiv3 import Window, TabNewClient
class Main:
def __init__(self):
window = Window()
tab1 = TabNewClient()
window.gbT1Main.setLayout(tab1.T1LayMain)
if __name__ == "__main__":
app = QApplication(sys.argv)
main = Main()
app.exec_()
That's most likely what you're looking for.
Important: this also requires that T1LayMain be an attribute of the TabNewClient class, so use self.T1LayMain inside that class for it to be accessible outside it.

pyqt5 / qtdesigner textbox default label

I am trying to create a GUI for my python program. One of the tools that I need is a text input box.
Now, I want a text label for this box saying "Please insert texts." Is there a function to add a label that shows inside the input textbox as default and disappear when user click the box to type?
I don't mind to use qt designer or pyqt5 coding.
Thank you guys.
placeholderText : QString
This property holds the line edit's placeholder text
import sys
from PyQt5.QtWidgets import QLineEdit, QVBoxLayout, QApplication, QWidget
class Test(QWidget):
def __init__(self):
super().__init__()
self.lineEdit = QLineEdit(placeholderText="Please insert texts.") # <---
vbox = QVBoxLayout(self)
vbox.addWidget(self.lineEdit)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Test()
w.show()
sys.exit(app.exec_())
I am begginer like you and my English is not so good. But I recommend you use Qt Designer. It's easier, fastter for you draw your app. I am using pyside2 project and recommend you read docummentatio each widgets you wanna use in PySide2 project and Qt Project. Try code below
enter image description here
import sys
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QDialog
from PySide2.QtWidgets import QTextEdit
from PySide2.QtWidgets import QVBoxLayout
from PySide2.QtCore import Qt
class MainDialog(QDialog):
def __init__(self, parent=None):
super(MainDialog, self).__init__(parent)
# Create Widget TextEdit
self.text = QTextEdit()
# I think that you wanna this function in your program
# https://doc.qt.io/qtforpython/PySide2/QtWidgets/QLineEdit.html?highlight=qlineedit#PySide2.QtWidgets.PySide2.QtWidgets.QLineEdit.setPlaceholderText
# http://doc.qt.io/qt-5/qlineedit.html#placeholderText-prop
self.text.setPlaceholderText('''Yes! this is exactly what I want!
Thank you, what if you have a big text box (more than 10 lines) and
you want to scale up the place holder and align it in center?? ''')
# https://doc.qt.io/qtforpython/PySide2/QtWidgets/QLineEdit.html?highlight=qlineedit#PySide2.QtWidgets.PySide2.QtWidgets.QLineEdit.setAlignment
# http://doc.qt.io/qt-5/qlineedit.html#alignment-prop
self.text.setAlignment(Qt.AlignCenter)
# Layout
layout = QVBoxLayout()
layout.addWidget(self.text)
self.setLayout(layout)
def main():
app = QApplication()
mainDialog = MainDialog()
mainDialog.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

How do I draw a plot using pyqtgraph on PyQt4 widget created in QT Designer?

I'm just starting with pyqtgraph. I have a graphicsView widget that I promoted with QT designer per the documentation. I would like to try a plot to see if it works. When I tried pg.plot(x,y) the program created a plot in a separate window rather than in the graphicsView widget. I'm using Windows 10, PyQt4, and Python 2.7. What am I doing wrong?
from PyQt4 import QtGui
from PyQt4 import QtCore
import ui_test #Gui File
import sys
import pyqtgraph as pg
class Gui(QtGui.QMainWindow, ui_test.Ui_MainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self) # This is defined in ui_pumptest.py file automatically
self.plot()
def plot(self):
vb = pg.ViewBox()
self.graphicsView.setCentralItem(vb)
def main():
app = QtGui.QApplication(sys.argv) # A new instance of QApplication
form = Gui() # We set the form to be our ExampleApp (design)
form.show() # Show the form
app.exec_() # and execute the. app
if __name__ == '__main__': # if we're running file directly and not importing it
main() # run the main function
Can you share the ui_pumptest.py file source? Otherwise it's hard to tell what your intentions are. If not, at least detail what construct you used to place in the QGraphicsView promotion process in QtDesigner (assuming you followed http://www.pyqtgraph.org/documentation/how_to_use.html#embedding-widgets-inside-pyqt-applications).
pg.plot creates it's own plotwindow->plotwidget structure, so that's why you're getting a separate window if calling that. The item you call plot on should be the container object name that was promoted in your Qt Ui file.

How does one make a button in the main window open a different window?

I am very new to this and have used the Qt Designer to make a very simple main window ui. The first functionality I want in my project is for a button to open a different window when clicked.
So basically I have the file autoGenUI.py that is generated using pyside-uic which includes
from PySide import QtCore, QtGui
class AutoGeneratedUI(object):
def setupUi(self, MainWindow):
#Auto generated code
def retranslateUi(self, MainWindow):
#Auto generated code
This all works fine of course because the Qt designer made it. I then have my own .py file that is basically my application stuff.
It looks like this:
import sys
from PySide.QtCore import *
from PySide.QtGui import *
from autoGenUI import *
class MyMainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent)
self.ui = AutoGeneratedUI()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QApplication(sys.argv)
myMainWindow = MyMainWindow()
myMainWindow.show()
sys.exit(app.exec_())
My button is called self.pushButton in the auto generated python UI. I would like to design another window and then call that window but for now anything will do. I just don't know where to put the code to make my button do something.
I tried to follow the docs but couldn't get anything to work.
Any help is greatly appreciated.
Thanks
You need to connect the clicked signal of pushButton to a method such as on_button_clicked():
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent)
self.ui = AutoGeneratedUI()
self.ui.setupUi(self)
# connect the clicked signal to on_button_clicked() method
self.pushButton.clicked.connect(self.on_button_clicked)
def on_button_clicked(self):
print "button clicked"
# here is the code to open a new window

Running python files

I am working on pyqt4 and python26 application.I created forms using qt designer (.ui files).
I converted them to .py and .pyc files.But when i try to run .py file ,python command line comes and goes within a second,the form (corresponding .ui file) cannot be seen...what can be the problem??
this is my code:(.py file)
from DlgAbout_ui import Ui_DlgAbout
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import resources
class DlgAbout(QDialog, Ui_DlgAbout):
def __init__(self, parent=None):
QDialog.__init__(self, parent)
self.setupUi(self)
self.logo.setPixmap( QPixmap( ":/icons/faunalia_logo.png" ) )
text = self.txt.toHtml()
text = text.replace( "$PLUGIN_NAME$", "RT Sql Layer" )
self.txt.setHtml(text)
First, don't use:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
Instead:
from PyQt4 import QtCore, QtGui
And reference the modules explicitly.
class DlgAbout(QtGui.QDialog, Ui_DlgAbout):
etc.
In your code, all you've done is defined a dialog box. You haven't defined any main application to run, or any way to show the dialog box.
For an example, here's a basic main application to run:
from PyQt4 import QtGui
import sys
class MyMainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent)
self.form_widget = FormWidget(self)
self.setCentralWidget(self.form_widget)
class FormWidget(QtGui.QWidget):
def __init__(self, parent):
super(FormWidget, self).__init__(parent)
self.layout = QtGui.QVBoxLayout(self)
self.button = QtGui.QPushButton("Button!")
self.layout.addWidget(self.button)
if __name__ == "__main__":
app = QtGui.QApplication([])
foo = MyMainWindow()
foo.show()
sys.exit(app.exec_())
This defines a main window, and a form (Which MyMainWindow sets up, as you can see).
I then check if this is the main file being run (if __name__ == "__main__":), and I start the application (The app = QtGui.QApplication([]), create the main window, and show the main window.
In your case, you could define a main application like I did, and make it alert your QDialog.
Your python code just imports some modules and then defines a new class. It doesn't do anything with the class it has defined, though. In other words, once Python is done creating the new class, it is finished, and it exits.
I don't know PyQT at all, but most likely you need to start the GUI's main loop, and also instantiate an instance of your new class and pass it to PyQT.

Categories