我正在使用 Docker 设置隔离的开发环境。因此,我配置了 dockerfile 来创建非 root 用户。(使用官方 Ubuntu 映像作为基础)我创建了一个用于文件管理的卷...
我正在使用 Docker 设置隔离的开发环境。因此我配置了 dockerfile 来创建非 root 用户。(使用官方 Ubuntu 镜像作为基础)
我创建了一个用于文件管理的卷,但是出现了权限问题。
为此审查了几种解决方案。:
我想应用解决方案2,但问题如下。
但是,为了使用 Docker 而修改外部环境似乎不太可取。因此,我决定不创建 1001:1001 的用户。
名为“ubuntu”的用户是一个已经创建的账户,如下所示。
$ docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
Digest: sha256:3f85b7caad41a95462cf5b787d8a04604c8262cdcdf9a472b8c52ef83375fe15
Status: Image is up to date for ubuntu:latest
docker.io/library/ubuntu:latest
What's Next?
1. Sign in to your Docker account → docker login
2. View a summary of image vulnerabilities and recommendations → docker scout quickview ubuntu
$ docker run --rm ubuntu cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash <-- ??
我想知道的是:
我正在寻找一种灵活、通用且不受外部环境影响的方法来解决这个问题。
当我创建一个小部件时,移动对我来说不起作用,我给它前一个窗口(而不是父窗口)的位置,但它仍然不想接受我在 Ubuntu 上的 Qt 中需要的位置,即使
当我创建一个小部件时,移动对我来说不起作用,我给它前一个窗口(而不是父窗口)的位置,但它仍然不想接受我在 Ubuntu 上的 Qt 中需要的位置,尽管在 Windows 上一切正常
代码:
if(query.next()){ // проверка результата запроса
QRect currentGeometry = this->geometry();
QWidget *loggetInWindow = createAccountWindow(userType, currentGeometry);
if(loggetInWindow){
loggetInWindow->show();
loggetInWindow->move(this->x(), this->y());
}
}
else{
QMessageBox::warning(this, "Ошибка входа", "Неверный логин или пароль.");
}
我尝试交换 show 和 move(我不知道哪个才是正确的)但什么都没改变
补充代码,LoginWindow 是程序启动时立即打开的第一个初始窗口,loggetInWindow 这是单击按钮后打开的第二个窗口
#include "ui_loginwindow.h"
#include "registrationwindow.h"
#include "loginwindow.h"
#include "adminwindow.h"
#include "clientwindow.h"
#include "workerwindow.h"
#include <QPropertyAnimation>
#include <QtSql/QSqlDatabase> // для подключения к базе данных
#include <QtSql/QSqlQuery> // для выполения запросов к базе данных
#include <QMessageBox>
LoginWindow::LoginWindow(QWidget *parent)
: QWidget(parent)
, ui(new Ui::LoginWindow)
{
ui->setupUi(this);
QComboBox *comboBox = ui->comboBox;
comboBox->addItem("Клиент");
comboBox->addItem("Администратор");
comboBox->addItem("Работник");
}
LoginWindow::~LoginWindow()
{
delete ui;
}
void LoginWindow::on_pushButton_login_clicked() // кнопка вход
{
QString userType = ui->comboBox->currentText();
QString username = ui->lineEdit_username->text();
QString password = ui->lineEdit_password->text();
{
QSqlDatabase db;
if(QSqlDatabase::contains("loginConnection")){
db = QSqlDatabase::database("loginConnection");
if(!db.open()){
qDebug() << "Failed open database LoginWindow\n";
return;
}
}
else{
db = QSqlDatabase::addDatabase("QMYSQL", "loginConnection");
db.setHostName("localhost");
db.setUserName("zxctatar");
db.setDatabaseName("zxctatar");
if(!db.open()){
qDebug() << "Failed open database LoginWindow\n";
return;
}
}
if(ui->lineEdit_username->text().length() == 0){
QMessageBox::warning(this,"LoginWindow","Введите логин");
return;
}
if(ui->lineEdit_password->text().length() == 0){
QMessageBox::warning(this,"Пароль", "Введите пароль");
return;
}
QSqlQuery query(db);
if(userType == "Клиент"){
query.prepare("SELECT * FROM Клиент WHERE Логин = :login AND Пароль = :password");
}
else if(userType == "Администратор"){
query.prepare("SELECT * FROM Администратор WHERE StrComp(Логин, :login, 0) = 0 AND StrComp(Пароль, :password, 0) = 0");
}
else if(userType == "Работник"){
query.prepare("SELECT * FROM Работник WHERE StrComp(Логин, :login, 0) = 0 AND StrComp(Пароль, :password, 0) = 0");
}
else{
qDebug() << "Unknown user type\n";
db.close();
return;
}
query.bindValue(":login", username);
query.bindValue(":password", password);
if (!query.exec()){
qDebug() << "Failed query\n";
db.close();
return;
}
if(query.next()){ // проверка результата запроса
QRect currentGeometry = this->geometry();
QWidget *loggetInWindow = createAccountWindow(userType, currentGeometry);
if(loggetInWindow){
loggetInWindow->show();
loggetInWindow->move(this->x(), this->y());
}
}
else{
QMessageBox::warning(this, "Ошибка входа", "Неверный логин или пароль.");
}
db.close();
}
QSqlDatabase::removeDatabase("loginConnection");
}
QWidget* LoginWindow::createAccountWindow(const QString& userType, const QRect& geometry){ // проверка какое окно создать
QWidget *loggedInWindow = nullptr;
if(userType == "Клиент"){
loggedInWindow = new ClientWindow(ui->lineEdit_username->text());
loggedInWindow->setAttribute(Qt::WA_DeleteOnClose);
}
else if(userType == "Администратор"){
loggedInWindow = new AdminWindow();
loggedInWindow->setAttribute(Qt::WA_DeleteOnClose);
}
else if(userType == "Работник"){
loggedInWindow = new WorkerWindow(ui->lineEdit_username->text());
loggedInWindow->setAttribute(Qt::WA_DeleteOnClose);
}
if(loggedInWindow){
loggedInWindow->setGeometry(geometry);
loggedInWindow->setWindowOpacity(0.0);
loggedInWindow->show();
}
return loggedInWindow;
}
void LoginWindow::on_pushButton_registration_clicked(){
RegistrationWindow* regWindow = new RegistrationWindow(this);
regWindow->setAttribute(Qt::WA_DeleteOnClose);
regWindow->show();
connect(regWindow, &RegistrationWindow::windowClosed, this, [=](){
delete regWindow;
});
}
最小可重复示例
#include "mainwindow.h"
#include <QScreen>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
QScreen *primaryScreen = QGuiApplication::primaryScreen();
QRect availableGeometry = primaryScreen->availableGeometry();
int x = (availableGeometry.width() - w.width()) / 2;
int y = (availableGeometry.height() - w.height()) / 2;
w.move(x,y);
w.show();
return a.exec();
}