Here you can find what is new and what is break under the PyQGIS API.
To get details about how to port Python2 to Python3 go there
You can find some detail about testing from QGIS2 to QGIS3 on this question :Writing automated tests for QGIS plugins?
And you will find an interesting OpenGis.ch's paper here about the migrations tools.
This is a bug in NNJoin plugin.
Open NNJoin_gui.py file located in "/Users/joanlee/Library/Application Support/QGIS/QGIS3/profiles/default/python/plugins/NNJoin/" using an editor.
Add from qgis.PyQt.QtWidgets import QMessageBox line to imports section.
Then save the file and (you may need to) restart QGIS.
Review this script. It creates a new QMainWindow and moves the existing map canvas to that window. I've made some changes. Firstly, add a file path (to QgsVectorLayer) to be displayed in map canvas.
from PyQt5 import QtCore, QtGui, QtWidgets
from qgis.gui import QgsMapCanvas
from qgis.core import QgsVectorLayer
I'm assuming when you say "PyQt5", you mean you are using QGIS 3.x. In which case:
layer = QgsMapLayerRegistry.instance().mapLayersByName('Layer_Name')
layer = QgsProject.instance().mapLayersByName('Layer_Name')
You can read here about the API changes and here for the PyQt4 and PyQt5 ...
I don't see the practical side of creating classes inside other classes. Just split it.
Below is how I will make your code work :
from PyQt5 import uic
from PyQt5.QtWidgets import QWidget
from qgis.core import QgsProcessingAlgorithm
FORM_CLASS, _ = uic.loadUiType("ui_file.ui")
class MyWidget(QWidget, FORM_CLASS)...
You don't need to define lambda function and to specify self.canvas.scale() and self.canvas.xyCoordinates(). Because scaleChanged event passes scale and xyCoordinates passes coordinates to the related functions you define, by default. Thus, try in that way:
For anyone interested, here is an implementation of a CheckableComboBox.
# Subclass Delegate to increase item height
def sizeHint(self, option, index):
size = super().sizeHint(option, index)
You can add the combobox to a dialog window. After closing the dialog, print prints the selected items.
from qgis.PyQt import QtGui
from qgis.core import *
planet_list = ["Venus", "Earth", "Mars", "Jupiter", "Pluto"]
items = QgsCheckableComboBox()
dlg = QDialog()
layout = ...
I don't know how to do that in Qt Designer, but in PyQGIS directly, it is an easiest way :
my_dlg = QDialog()
my_dlg_lyt = QVBoxLayout(my_dlg)
my_msg_bar = QgsMessageBar(my_dlg)
pb = QPushButton("test")
my_msg_bar.pushMessage("It works", "I'm so happy ...
The environment and path needs to be set for Qt Designer to access the QGIS Custom widgets. These can be set by running the "qgis-designer.bat" file that comes with a QGIS installation. For a network installation, this file is located in:
The contents of this batch file are:
In QGIS 3.2.0, custom widgets seem to be available:
Tested on Windows 7 64-bit.
I used the QGIS Standalone Installer Version 3.2 (64 bit) and following the simple on-screen instructions. Once installed, I simply ran Qt Designer with QGIS 3.2.0 custom widgets.exe which was found in the Start menu.
I also tested QGIS Standalone Installer Version 3.2 (...
You need to connect your LIVSMILJO comboBox to a signal and return the current text of LIVSMILJO comboBox every time selection of text changes in LIVSMILJO comboBox.This can be done as follows
txt = self.dlg.LIVSMILJO.currentText()
In QGIS you can't use an application object, because qgis itself is a QtApplication. Try to execute lines 6-10 alone and you'll see a widget on the screen. To have a full functional dialog, you'll need to a have something like a qgis-plugin. To work with pyqt only, try an standalone python shell or an ide.
For plugin creation, you use the qgis plugin "...
I have found an answer:
con = ['name_of_db','C:\\path_to_db\\andorra.sqlite']
QSettings().setValue("SpatiaLite/connections/%s/sqlitepath" %(con), con)
This code will create an 'visible' connection with the given sqlite database.
conn = sqlite3.connect(r'C:\\path_to_db\\andorra.sqlite')
uri = ...
Test-it in another method like that :
def run (self):
self.dlg = Dialog()
self.dlg.horizontalSlider.sliderMoved.connect(lambda v: self.adjust_sliders(1, v))
self.dlg.horizontalSlider_2.sliderMoved.connect(lambda v: self.adjust_sliders(2, v))
def adjust_sliders(self, slider_num, moved_value):
In a plugin (displayed "Always On Top"), with PyQGIS 3, to avoid it jumps right to the end without calling the display_point function you need following changes in your code:
from PyQt5.QtCore import Qt
from qgis.gui import QgsMapToolEmitPoint
def __init__(self, iface):
# Create the dialog (after ...
Perhaps it is due to some bug in QGIS 3.0 as it was the case with QGIS 2.18 see https://issues.qgis.org/issues/16743 one thing you can do to solve this issue is to install latest version QGIS 3.0.2 from https://qgis.org/en/site/forusers/download.html and hope that it was taken care of or you can report it as bug.
It is likely because each time the plugin is run, you are adding another connect signal to the function. You should disconnect this at the end of your loadDate(self) function using:
In python you have "events" and "events handler". when an event occurs they usually (not always...) generate a signal that can be caught by the event handler.
for example :
the event is selectionChanged and the event handler is the function handling the signal received (in that case the handler should be a ...
Just had a similar problem, a solution might be to add a layout and add the labels, lineedit and comboxes in to it, also make sure that they are large enough (that the minimum width is large enough etc.
To open and close layouts programmatically in QGIS 3.4, you could use something like this:
Open a layout by name:
layout_name = 'Test'
layout = QgsProject().instance().layoutManager().layoutByName(layout_name)
Then closing the layout is as simple as:
To close a layout by its name:
Note that you are creating a new instance of your dialog class every time the run() method is called. The isVisible() method is always returning false because you are calling it on the new instance of your dialog before you ever call show() on that object.
Why don't you declare self.dlg as an instance variable in the __init__() method.